or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdcomponents.mdcore-framework.mddata-integration.mdindex.mdlayouts.mdsecurity.mdthemes-styling.md

security.mddocs/

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