Access control based on roles or permissions
- hasAuthority method
If the current principal has the specified authority, it returns true, otherwise it returns false- What permissions are available for setting the current access address in the configuration class
//当前登录用户,只要具有admin权限才可以访问这个路径 .antMatchers("/test/index").hasAuthority("admin")
- In UserDetailsService, set permissions on the returned User object
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
- type=Forbidden, status=403 means no access
- hasAnyAuthority method
returns true if the current principal has any of the provided roles
.antMatchers("/test/index").hasAnyAuthority("admin,manager")
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
- hasRole method
- The prefix "ROLE_" must be added when assigning roles
.antMatchers("/test/index").hasRole("sale")
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
Assert.isTrue(!role.startsWith("ROLE_"), () -> {
return "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'";
});
return "hasRole('ROLE_" + role + "')";
}
- hasAnyRole method The
user can access any one of them
Custom 403 page
http.exceptionHandling().accessDeniedPage("/unauth.html");
Authentication and authorization annotation use
- @Secured annotation, the user has a certain role and can access the method
- Startup class (configuration class) open annotation
@EnableGlobalMethodSecurity(securedEnabled = true)
- Use annotations on the Controller method to set the role
@GetMapping("/secured") @Secured({ "ROLE_sale","ROLE_manager"}) public String secured(){ return "hello secured"; }
- userDetailsService sets user roles
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");
- @PreAuthorize: check before the method is executed
- Open annotation
@EnableGlobalMethodSecurity(prePostEnabled = true)
- Use annotations on the controller method
@GetMapping("/preAuthorize") @PreAuthorize("hasAnyAuthority('admin,manager')") public String preAuthorize(){ return "hello PreAuthorize"; }
- @PostAuthorize: Verify after the method is executed
- @PostFilter: Filter the data returned by the method
@GetMapping("/testFilter")
@PreAuthorize("hasAnyAuthority('admin,manager')")
@PostFilter("filterObject.username == 'admin11'")
public List<User> testFilter(){
ArrayList<User> list = new ArrayList<>();
list.add(new User(11,"admin11","111"));
list.add(new User(22,"admin22","222"));
System.out.println(list);
return list;
}
Console output
[User(id=11, username=admin11, password=111), User(id=22, username=admin22, password=222)]
Front-end output
[
{
id: 11,
username: "admin11",
password: "111"
}
]
- @PreFilter: Filter the data before entering the controller
User logout
- Add an exit configuration in the configuration class
http.logout().logoutUrl("/logout")
.logoutSuccessUrl("/test/hello").permitAll();
- test
- Modify the configuration class and jump to the success page after successful login
- Add a hyperlink on the success page and write the exit path
- After the login is successful, click to log out on the success page, and then go to visit other controllers can not be accessed
auto login
- Realization principle
- Implementation
- Create database table
- Modify the configuration class and inject the data source
//注入数据源 @Autowired private DataSource dataSource; //配置对象 @Bean public PersistentTokenRepository persistentTokenRepository(){ JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); jdbcTokenRepository.setDataSource(dataSource); jdbcTokenRepository.setCreateTableOnStartup(true); return jdbcTokenRepository; }
- Configure automatic login in the configuration class
.rememberMe().tokenRepository(persistentTokenRepository()) .tokenValiditySeconds(60)
- Add checkbox to login page
<input type="checkbox" name="remember-me">自动登录
- Information stored in the database
CSRF: Cross-site request forgery
-
principle
-
Default on
-
For PATCH, POST, PUT, DELETE
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
- GET, HEAD, TRACE, OPTIONS are not protected