SpringBoot整合SpringSecurity

需要使用的jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

核心配置

@Configuration
@EnableWebSecurity
//开启可以通过在方法中加入注解来实现权限控制
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    /**
     * 配置认证
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
    }

    /**
     * 配置授权
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
}

登录认证配置

实现用户认证登录的接口:UserDetailsService

public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = userService.findUserInfoByUsername(username);
        List<GrantedAuthority> userAuthority = getUserAuthority(user.getId());
        //UserDetails的自定义实现类
        AccountUser accountUser = new AccountUser(user.getUsername(),user.getPassword(),true,getUserAuthority(user.getId()));
        return accountUser;
    }

    //查询用户权限
    public List<GrantedAuthority> getUserAuthority(Long userId){
        String userAuthority = userService.getUserAuthority(userId);
        List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(userAuthority);
        return grantedAuthorities;
    }
}

UserDetails的自定义实现类

public class AccountUser implements UserDetails {

    //用户名
    private String username;
    //密码
    private String password;
    //账号是否过期(true:没有过期,false:过期)
    private Boolean isAccountNonExpired;
    //账号是否被锁定(true:没有,false:锁定)
    private Boolean isAccountNonLocked;
    //密码是否过期(true:没有过期,false:过期)
    private Boolean isCredentialsNonExpired;
    //账号是否可用(true:可用,false:不可用)
    private Boolean isEnabled;
    //权限集合
    private Collection<? extends GrantedAuthority> authorities;

    public AccountUser(String username, String password, Boolean isEnabled, Collection<? extends GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.isEnabled = isEnabled;
        this.authorities = authorities;
        //赋予其它属性默认值
        this.isAccountNonExpired = true;
        this.isAccountNonLocked = true;
        this.isCredentialsNonExpired = true;
    }
    public AccountUser(String username, String password, Boolean isAccountNonExpired, Boolean isAccountNonLocked, Boolean isCredentialsNonExpired, Boolean isEnabled, Collection<? extends GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.isAccountNonExpired = isAccountNonExpired;
        this.isAccountNonLocked = isAccountNonLocked;
        this.isCredentialsNonExpired = isCredentialsNonExpired;
        this.isEnabled = isEnabled;
        this.authorities = authorities;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }
    @Override
    public String getPassword() {
        return this.password;
    }
    @Override
    public String getUsername() {
        return this.username;
    }
    @Override
    public boolean isAccountNonExpired() {
        return this.isAccountNonExpired;
    }
    @Override
    public boolean isAccountNonLocked() {
        return this.isAccountNonLocked;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return this.isCredentialsNonExpired;
    }
    @Override
    public boolean isEnabled() {
        return this.isEnabled;
    }
}

查询用户权限

public String getUserAuthority(Long userId) {
        String authority = "";
        //根据用户ID获取到角色信息列表
        List<SysRole> roleList =  userMapper.selectUserAuthorityRoleByUserId(userId);
        //设置用户权限的角色信息
        authority = roleList.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
        authority = authority.concat(",");
        //设置用户的权限列表
        List<SysMenu> menuList = userMapper.selectUserAuthorityMenuByUserId(userId);
        String menus = menuList.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
        authority = authority.concat(menus);
        return authority;
    }

认证改造

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;
    @Autowired
    private LoginFailedHandler loginFailedHandler;


    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 认证配置
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService());
    }

    /**
     * 授权配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()//配置允许跨域

                .formLogin() //登录配置
                    .successHandler(loginSuccessHandler)  //认证成功处理
                    .failureHandler(loginFailedHandler)   //认证失败处理

                .and()
                    .authorizeRequests().antMatchers("/白名单").permitAll() //放行白名单
                    .anyRequest().authenticated() //拦截其它请求,需要先经过认证


                .and()
                    .exceptionHandling()
                    .authenticationEntryPoint(null) //认证异常的处理
                    .accessDeniedHandler(null) //权限不足处理

                .and()
                    .addFilter(null) //添加拦截器
                    .addFilterBefore(null,null) //在哪个拦截器之前执行
                    .addFilterAfter(null,null); //在哪个拦截器之后执行

    }
}

授权

package com.sailencoding.config.security;

import com.sailencoding.security.LoginFailedHandler;
import com.sailencoding.security.LoginSuccessHandler;
import com.sailencoding.security.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @Author JavaCat
 * @CreateTime 2021/9/4 20:51
 * @Desc
 **/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()//配置允许跨域

                .formLogin() //登录配置
                    .successHandler(loginSuccessHandler)  //认证成功处理
                    .failureHandler(loginFailedHandler)   //认证失败处理

                .and()
                    .authorizeRequests().antMatchers("/白名单").permitAll() //放行白名单
                    .anyRequest().authenticated() //拦截其它请求,需要先经过认证


                .and()
                    .exceptionHandling()
                    .authenticationEntryPoint("传递异常处理类") //认证异常的处理
                    .accessDeniedHandler("传递权限不足处理类") //权限不足处理

                .and()
                    .addFilter(null) //添加拦截器
                    .addFilterBefore("执行的拦截器","在哪个拦截器之前") //在哪个拦截器之前执行
                    .addFilterAfter("执行的拦截器","在哪个拦截器之后"); //在哪个拦截器之后执行

    }
}