一、SpringSecurity工作原理
如果对Spring-Security工作原理还不太清楚的的同学可以访问我之前的博客SpringSecurity登录认证授权原理,写的很详细
二、Springboot与SpringSecurity的整合
1.用户类User实现UserDetails接口,并重写其方法
@Table(name = "db_user")
@Entity
public class User implements Serializable,UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;//主键id
@Transient
private List<Role> roles;//角色集合
...(其他字段省略)
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(roles == null || roles.size()<=0){
return null;
}
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
for(Role r:roles){
authorities.add(new SimpleGrantedAuthority(r.getRoleName()));
}
return authorities;
}
@Override
public String getUsername() {
if(email != null){
return email;
}else {
return phone;
}
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
if(StringUtils.isNotBlank(state) && "1".equals(state) && !deleteFlag){
return true;
}
return false;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
return getEmail().equals(((User)obj).getEmail())||getUsername().equals(((User)obj).getUsername());
}
return false;
}
@Override
public int hashCode() {
return getUsername().hashCode();
}
因为我们需要实现自己获取用户信息的方式,必须得实现UserDetails接口。其中账号未过期、账号未锁定、密码未过期这里统一返回true,因为我们没有使用场景,只对其中的账号是否可用进行判断。我这里主要是根据账号有没有激活和是否删除进行判断,大家可根据自己的情况进行判断。
getAuthorities()是获取角色信息的方法
2.自定义AccountDetailsService并实现UserDetailsService接口
public class AccountDetailsService implements UserDetailsService {
@Autowired
UserService userService;
@Autowired
private RoleService roleService;
@Override
@LoggerManager( description = "根据用户名进行登录")
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userService.findByEmail( email );
if (user == null) {
throw new UsernameNotFoundException( "用户名或密码错误" );
}
List<Role> roles = roleService.findByUid( user.getId() );
user.setRoles( roles );
return user;
}
}
自定义获取用户信息的业务逻辑,账号登录就根据邮箱去查询用户
3.自定义账号登录过滤器AccountAuthenticationFilter
public class AccountAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private String usernameParameter = "username";
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
String username = this.obtainUsername(request);
String password = this.obtainPassword(request);
if(username == null) {
username = "";
}
if(password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(this.usernameParameter);
}
}
4.核心配置WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
/**
* 添加认证策略
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider( usernameAndPasswordAuthenticationProvider() );
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home","/index","/api/**","/doRegister").permitAll()// 允许访问home、注册登录url
.antMatchers( "/user/**" ).hasAnyRole( "USER" )//需要ROLE_USER权限
.antMatchers( "/yvpai" ).hasRole( "ADMIN" )//需要ROLE_ADMIN权限
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")//登录页面允许访问
.permitAll()
.and()
.logout()//注销页面允许访问
.permitAll();
http.addFilterBefore( accountAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class );//添加自定义过滤器
}
/**
* 账号登录认证过滤器
* @return
*/
@Bean
public AccountAuthenticationFilter accountAuthenticationFilter(){
AccountAuthenticationFilter accountAuthenticationFilter = new AccountAuthenticationFilter();
accountAuthenticationFilter.setAuthenticationManager( authenticationManager );
return accountAuthenticationFilter;
}
/**
* 注册Bean
* @return
* @throws Exception
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 默认的账号登录认证策略
* @return
*/
@Bean
public AbstractUserDetailsAuthenticationProvider usernameAndPasswordAuthenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService( accountDetailsService() );
daoAuthenticationProvider.setPasswordEncoder( bCryptPasswordEncoder() );//设置密码策略
return daoAuthenticationProvider;
}
/**
* 注册Bean
* @return
*/
@Bean
public AccountDetailsService accountDetailsService(){
return new AccountDetailsService();
}
/**
* 注册Bean
* @return
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
WebSecurityConfig主要配置了登录认证策略、密码策略、获取用户业务逻辑、登录过滤器、哪些资源放行、哪些资源需要什么样的权限才能访问等。
关注我的微信公众号获取更多资源

本文详细介绍如何在SpringBoot项目中整合SpringSecurity,包括自定义用户类、账号登录过滤器及核心配置,实现登录认证与权限控制。
2420

被折叠的 条评论
为什么被折叠?



