0
# Security
1
2
Vaadin provides comprehensive security features for controlling access to views and securing applications, with seamless integration with Spring Security and Jakarta EE security.
3
4
## Security Annotations
5
6
Annotations for controlling access to views and endpoints.
7
8
```java { .api }
9
/**
10
* Allows anonymous (unauthenticated) access to a view
11
* Place on view classes to make them publicly accessible
12
*/
13
@Target(ElementType.TYPE)
14
@Retention(RetentionPolicy.RUNTIME)
15
@interface AnonymousAllowed {
16
}
17
18
/**
19
* Allows all authenticated users to access a view
20
* Place on view classes to require authentication but no specific roles
21
*/
22
@Target(ElementType.TYPE)
23
@Retention(RetentionPolicy.RUNTIME)
24
@interface PermitAll {
25
}
26
27
/**
28
* Restricts access to users with specific roles
29
* Place on view classes to require specific role membership
30
*/
31
@Target(ElementType.TYPE)
32
@Retention(RetentionPolicy.RUNTIME)
33
@interface RolesAllowed {
34
/**
35
* Array of role names that are allowed to access the view
36
* @return Array of allowed role names
37
*/
38
String[] value();
39
}
40
41
/**
42
* Denies all access to a view
43
* Place on view classes to completely block access
44
*/
45
@Target(ElementType.TYPE)
46
@Retention(RetentionPolicy.RUNTIME)
47
@interface DenyAll {
48
}
49
```
50
51
**Usage Examples:**
52
53
```java
54
import com.vaadin.flow.server.auth.AnonymousAllowed;
55
import jakarta.annotation.security.PermitAll;
56
import jakarta.annotation.security.RolesAllowed;
57
import jakarta.annotation.security.DenyAll;
58
59
// Public view accessible to everyone
60
@Route("welcome")
61
@AnonymousAllowed
62
public class WelcomeView extends VerticalLayout {
63
public WelcomeView() {
64
add(new H1("Welcome!"));
65
add(new Paragraph("This page is public"));
66
}
67
}
68
69
// View accessible to any authenticated user
70
@Route("dashboard")
71
@PermitAll
72
public class DashboardView extends VerticalLayout {
73
public DashboardView() {
74
add(new H1("Dashboard"));
75
add(new Paragraph("You are logged in"));
76
}
77
}
78
79
// View restricted to specific roles
80
@Route("admin")
81
@RolesAllowed({"ADMIN", "SUPER_USER"})
82
public class AdminView extends VerticalLayout {
83
public AdminView() {
84
add(new H1("Admin Panel"));
85
add(new Paragraph("Admin access only"));
86
}
87
}
88
89
// View completely blocked
90
@Route("maintenance")
91
@DenyAll
92
public class MaintenanceView extends VerticalLayout {
93
// This view cannot be accessed
94
}
95
```
96
97
## Spring Security Integration
98
99
Classes for integrating Vaadin with Spring Security.
100
101
```java { .api }
102
/**
103
* Base configuration class for Spring Security with Vaadin
104
* Extend this class to configure security for Vaadin applications
105
*/
106
abstract class VaadinWebSecurity extends WebSecurityConfigurerAdapter {
107
/**
108
* Configures HTTP security for the application
109
* @param http - HttpSecurity to configure
110
* @throws Exception if configuration fails
111
*/
112
protected void configure(HttpSecurity http) throws Exception;
113
114
/**
115
* Configures web security for the application
116
* @param web - WebSecurity to configure
117
* @throws Exception if configuration fails
118
*/
119
protected void configure(WebSecurity web) throws Exception;
120
121
/**
122
* Sets the login view and configures logout
123
* @param http - HttpSecurity to configure
124
* @param loginPath - Path to login view (e.g., "/login")
125
* @param logoutSuccessUrl - URL to redirect after logout
126
* @throws Exception if configuration fails
127
*/
128
protected void setLoginView(HttpSecurity http, String loginPath,
129
String logoutSuccessUrl) throws Exception;
130
131
/**
132
* Sets the login view
133
* @param http - HttpSecurity to configure
134
* @param loginPath - Path to login view
135
* @throws Exception if configuration fails
136
*/
137
protected void setLoginView(HttpSecurity http, String loginPath) throws Exception;
138
}
139
140
/**
141
* Context for accessing authentication information
142
* Injectable Spring bean for working with authentication
143
*/
144
class AuthenticationContext {
145
/**
146
* Checks if the current user is authenticated
147
* @return true if user is authenticated
148
*/
149
boolean isAuthenticated();
150
151
/**
152
* Gets the authenticated user object
153
* @param userType - Class of the user object
154
* @return Optional containing user if authenticated
155
*/
156
<T> Optional<T> getAuthenticatedUser(Class<T> userType);
157
158
/**
159
* Gets principal name of authenticated user
160
* @return Optional containing principal name
161
*/
162
Optional<String> getPrincipalName();
163
164
/**
165
* Logs out the current user
166
*/
167
void logout();
168
}
169
```
170
171
**Usage Examples:**
172
173
```java
174
import com.vaadin.flow.spring.security.VaadinWebSecurity;
175
import com.vaadin.flow.spring.security.AuthenticationContext;
176
import org.springframework.context.annotation.Configuration;
177
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
178
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
179
180
// Security configuration
181
@Configuration
182
@EnableWebSecurity
183
public class SecurityConfig extends VaadinWebSecurity {
184
@Override
185
protected void configure(HttpSecurity http) throws Exception {
186
super.configure(http);
187
setLoginView(http, "/login", "/");
188
}
189
}
190
191
// Using AuthenticationContext in a view
192
@Route("profile")
193
@PermitAll
194
public class ProfileView extends VerticalLayout {
195
public ProfileView(AuthenticationContext authContext) {
196
if (authContext.isAuthenticated()) {
197
Optional<UserDetails> userDetails =
198
authContext.getAuthenticatedUser(UserDetails.class);
199
200
userDetails.ifPresent(user -> {
201
add(new H2("Profile"));
202
add(new Paragraph("Username: " + user.getUsername()));
203
});
204
205
Button logoutButton = new Button("Logout", e -> {
206
authContext.logout();
207
});
208
add(logoutButton);
209
}
210
}
211
}
212
```
213
214
## Login Components
215
216
```java { .api }
217
class LoginForm extends Component {
218
LoginForm();
219
void setAction(String action);
220
void setError(boolean error);
221
void setErrorMessage(String errorMessage);
222
void setForgotPasswordButtonVisible(boolean visible);
223
void setI18n(LoginI18n i18n);
224
Registration addLoginListener(ComponentEventListener<LoginEvent> listener);
225
}
226
227
class LoginOverlay extends Component {
228
LoginOverlay();
229
void open();
230
void setOpened(boolean opened);
231
void setTitle(String title);
232
void setDescription(String description);
233
void setAction(String action);
234
void setError(boolean error);
235
Registration addLoginListener(ComponentEventListener<LoginOverlayEvent> listener);
236
}
237
238
class LoginEvent extends ComponentEvent<LoginForm> {
239
String getUsername();
240
String getPassword();
241
}
242
```
243
244
**Examples:**
245
246
```java
247
@Route("login")
248
@AnonymousAllowed
249
public class LoginView extends VerticalLayout {
250
public LoginView() {
251
LoginForm loginForm = new LoginForm();
252
loginForm.setAction("login");
253
loginForm.setForgotPasswordButtonVisible(false);
254
255
loginForm.addLoginListener(e ->
256
System.out.println("Login: " + e.getUsername())
257
);
258
259
add(new H1("Login"), loginForm);
260
setAlignItems(Alignment.CENTER);
261
}
262
}
263
264
@Route("")
265
@AnonymousAllowed
266
public class WelcomeView extends VerticalLayout {
267
private LoginOverlay loginOverlay;
268
269
public WelcomeView() {
270
loginOverlay = new LoginOverlay();
271
loginOverlay.setTitle("My Application");
272
loginOverlay.setDescription("Enterprise System");
273
loginOverlay.setAction("login");
274
275
LoginI18n i18n = LoginI18n.createDefault();
276
i18n.getForm().setTitle("Sign In");
277
i18n.getForm().setUsername("Email");
278
loginOverlay.setI18n(i18n);
279
280
loginOverlay.setOpened(true);
281
add(loginOverlay);
282
}
283
}
284
```
285
286
## Menu Access Control
287
288
Interfaces for controlling menu visibility based on user permissions.
289
290
```java { .api }
291
/**
292
* Interface for controlling access to menu items
293
*/
294
interface MenuAccessControl {
295
/**
296
* Populates menu based on user access rights
297
* @param request - Current HTTP request
298
* @return MenuRegistry with accessible items
299
*/
300
MenuRegistry populateClientSideMenu(HttpServletRequest request);
301
302
/**
303
* Checks if user can access a menu entry
304
* @param entry - Menu entry to check
305
* @param request - Current HTTP request
306
* @return true if access is allowed
307
*/
308
boolean canAccessMenuEntry(MenuEntry entry, HttpServletRequest request);
309
}
310
311
/**
312
* Default implementation of menu access control
313
* Uses security annotations to determine access
314
*/
315
class DefaultMenuAccessControl implements MenuAccessControl {
316
/**
317
* Creates default menu access control
318
* @param accessChecker - Access checker for views
319
*/
320
DefaultMenuAccessControl(AccessAnnotationChecker accessChecker);
321
}
322
323
/**
324
* Checker for security annotations on views
325
*/
326
class AccessAnnotationChecker {
327
/**
328
* Checks if principal has access to a view
329
* @param viewClass - View class to check
330
* @param principal - User principal
331
* @param roleChecker - Function to check roles
332
* @return true if access is allowed
333
*/
334
boolean hasAccess(Class<?> viewClass, Principal principal,
335
Function<String, Boolean> roleChecker);
336
}
337
```
338
339
## Security Best Practices
340
341
When securing Vaadin applications:
342
343
1. **Always use annotations on view classes**: Place security annotations (@AnonymousAllowed, @PermitAll, @RolesAllowed, @DenyAll) on all route classes.
344
345
2. **Deny by default**: Views without security annotations are denied by default. Always be explicit about access.
346
347
3. **Server-side validation**: Always validate user permissions on the server side, never rely solely on UI-level hiding.
348
349
4. **Use Spring Security integration**: Leverage VaadinWebSecurity for comprehensive Spring Security integration.
350
351
5. **Secure endpoints**: If using Vaadin Fusion or Hilla, secure backend endpoints with security annotations.
352
353
6. **Session management**: Configure proper session timeout and management in application properties.
354
355
**Example Comprehensive Security Setup:**
356
357
```java
358
// Security configuration
359
@Configuration
360
@EnableWebSecurity
361
public class SecurityConfiguration extends VaadinWebSecurity {
362
363
@Override
364
protected void configure(HttpSecurity http) throws Exception {
365
// Vaadin-specific security configuration
366
super.configure(http);
367
368
// Set login view
369
setLoginView(http, LoginView.class);
370
}
371
372
@Bean
373
public PasswordEncoder passwordEncoder() {
374
return new BCryptPasswordEncoder();
375
}
376
377
@Bean
378
public UserDetailsService userDetailsService() {
379
return new CustomUserDetailsService();
380
}
381
}
382
383
// Login view (public)
384
@Route("login")
385
@AnonymousAllowed
386
public class LoginView extends VerticalLayout {
387
public LoginView(AuthenticationContext authContext) {
388
if (authContext.isAuthenticated()) {
389
// Redirect if already logged in
390
getUI().ifPresent(ui -> ui.navigate(""));
391
}
392
393
LoginForm loginForm = new LoginForm();
394
loginForm.setAction("login");
395
loginForm.setForgotPasswordButtonVisible(false);
396
397
add(new H1("My Application"), loginForm);
398
}
399
}
400
401
// Main view (authenticated users only)
402
@Route("")
403
@PermitAll
404
public class MainView extends AppLayout {
405
public MainView(AuthenticationContext authContext) {
406
H1 title = new H1("My Application");
407
408
authContext.getAuthenticatedUser(UserDetails.class)
409
.ifPresent(user -> {
410
Button logout = new Button("Logout", e -> authContext.logout());
411
addToNavbar(title, logout);
412
});
413
414
addToDrawer(createMenu(authContext));
415
}
416
417
private Component createMenu(AuthenticationContext authContext) {
418
SideNav menu = new SideNav();
419
menu.addItem(new SideNavItem("Dashboard", "/dashboard"));
420
421
// Conditionally show admin link
422
authContext.getAuthenticatedUser(UserDetails.class)
423
.ifPresent(user -> {
424
if (user.getAuthorities().stream()
425
.anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) {
426
menu.addItem(new SideNavItem("Admin", "/admin"));
427
}
428
});
429
430
return menu;
431
}
432
}
433
434
// Admin view (admin role only)
435
@Route(value = "admin", layout = MainView.class)
436
@RolesAllowed("ADMIN")
437
public class AdminView extends VerticalLayout {
438
public AdminView() {
439
add(new H2("Admin Panel"));
440
add(new Paragraph("Only administrators can see this."));
441
}
442
}
443
```
444
445
## Jakarta EE Security
446
447
Vaadin also supports Jakarta EE (formerly Java EE) security annotations:
448
449
```java
450
import jakarta.annotation.security.RolesAllowed;
451
import jakarta.annotation.security.PermitAll;
452
import jakarta.annotation.security.DenyAll;
453
454
@Route("enterprise")
455
@RolesAllowed("ENTERPRISE_USER")
456
public class EnterpriseView extends VerticalLayout {
457
// Jakarta EE security integration
458
}
459
```
460
461
## CSRF Protection
462
463
Vaadin automatically handles CSRF (Cross-Site Request Forgery) protection:
464
465
- CSRF tokens are automatically included in all server requests
466
- No manual configuration needed for standard Vaadin applications
467
- Works seamlessly with Spring Security CSRF protection
468
469
## Related Documentation
470
471
- Spring Security: https://spring.io/projects/spring-security
472
- Jakarta Security: https://jakarta.ee/specifications/security/
473
- Vaadin Security Guide: https://vaadin.com/docs/latest/security
474