一、使用场景
springboot、springSecurity、mybatis 基于角色的权限控制
二、参考文献
https://liuyanzhao.com/7431.html
说明:网上查了一圈,只按照以上这篇博客实践成功,本文仅仅是自己实践的一些记录
三、坑
3.1
User 最好是implements UserDetails
public class User implements UserDetails {
3.2
User里角色对象要用Authority implements GrantedAuthority描述,不要用自定义的枚举或者字符串
private List
public class Authority implements GrantedAuthority { private String id; private String username; private String role;
3.3
SecurityConfig配置使用hasRole()时,不要在前面加.anyRequest().authenticated(),在最后面可以加,加在前面会使hasRole()失效
protected void configure(HttpSecurity http) throws Exception { http.formLogin().loginPage("/login").permitAll().failureUrl("/error").and().logout().logoutSuccessUrl("/login").permitAll().and().rememberMe().alwaysRemember(true) .and().authorizeRequests() // .anyRequest().authenticated() 这行不能加在前面 .antMatchers("/").hasRole("USER") .antMatchers("/manager/**").hasRole("ROOT") .antMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() .and().csrf().disable(); }
3.4
数据库里的角色要加前缀ROLE_ 例如:ROLE_ROOT
而SecurityConfig配置里要写不带前缀的例如.antMatchers("/").hasRole("ROOT")
四、解决方案
4.1 环境
jdk 8、springboot 2.0.1.RELEASE、maven、mybatis
4.2 关键依赖
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
4.3 实体类
User
package com.xp.entity;
import org.apache.ibatis.annotations.Many;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class User implements UserDetails, Serializable {
private String username;
private String password;
private List<Authority> authoritys;
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> simpleAuthorities = new ArrayList<>();
for(GrantedAuthority authority : this.authoritys){
simpleAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
}
return simpleAuthorities;
}
}
Authority 角色
public class Authority implements GrantedAuthority {
private String id;
private String username;
private String role;
}
UserMapper(基于mybits注解)
可以参考:https://my.oschina.net/Cubicluo/blog/1817659
配置类
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)// 启用方法安全设置
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder passwordEncoder;
@Bean
CustomUserService customUserService() {
return new CustomUserService();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(customUserService());
authenticationProvider.setPasswordEncoder(passwordEncoder); // 设置密码加密方式
return authenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception { http.formLogin().loginPage("/login").permitAll().failureUrl("/error").and().logout().logoutSuccessUrl("/login").permitAll().and().rememberMe().alwaysRemember(true)
.and().authorizeRequests()
// .anyRequest().authenticated() 这行不能加
.antMatchers("/").hasRole("USER")
.antMatchers("/manager/**").hasRole("ROOT")
.antMatchers("/user/**").hasRole("USER")
.and().csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService());
auth.authenticationProvider(authenticationProvider());
}
}