SpringBoot整合SpringSecurity进行认证授权

一、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 roles;//角色集合
...(其他字段省略)

 @Override
public Collection getAuthorities() {
    if(roles == null || roles.size()<=0){
        return null;
    }
    List authorities = new ArrayList();
    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 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进行认证授权_第1张图片

你可能感兴趣的:(SpringBoot)