目录
1.spring Security配置WebSecurityConfig
2.jwt身份拦截器JwtAuthenticationTokenFilter
4.权限认证失败处理类WAccessDeniedHandler
5.JwtAuthenticationProvider实现AuthenticationProvider接口,进行用户身份验证
6.继承UserDetailsService,从数据库获取用户信息
7.自定义UserDetailsBo类,继承UserDetails
8.自定义权限校验PermissionCheckServiceImpl
(1) jdk版本和springboot版本
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<springboot.version>3.1.5</springboot.version>
</properties>
(2) 流程说明(可以对照代码实现)
1.springboot启动时,会先加载WebSecurityConfig配置
(1)WebSecurityConfig里会跳过指定的url【requestMatchers("/auth/login").permitAll()】
(2)增加过滤器【.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)】
(3)绑定认证失败类:exceptionHandling(exce->exce.authenticationEntryPoint(unauthorizedHandler))
(4)绑定权限校验失败类:exceptionHandling(exce->exce.accessDeniedHandler(wAccessDeniedHandler))
2.当/auth/login请求进入时,会先到JwtAuthenticationTokenFilter过滤器,判断请求头中是否有token,因为没有token直接filterChain.doFilter(request, response)下一步,又因为在WebSecurityConfig配置了过滤,不会进入异常类,会直接到达AuthController,
会进入到LoginServiceImpl类,根据用户名和密码进行校验【authenticationManager.authenticate(authentication),真正进行校验的实现类JwtAuthenticationProvider】,校验通过则返回token,
否则抛出异常,返回错误信息。
3.当其它请求进入时,也会先到JwtAuthenticationTokenFilter过滤器,
如果有token,则解析token,获取用户信息,然后设置到SecurityContextHolder中,如果解析失败,则抛出异常,进入异常处理类,返回错误信息。
如果没有token,则会被拦截,进入异常处理类,返回错误信息
(3) 代码实现
1.spring Security配置WebSecurityConfig
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
private UnauthorizedHandler unauthorizedHandler;
@Autowired
private WAccessDeniedHandler wAccessDeniedHandler;
/**
* 认证管理
* @param configuration
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}
/**
* 认证过滤器
* @return
*/
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
return new JwtAuthenticationTokenFilter();
}
/**
* 密码加密
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 权限校验
* @return
*/
@Bean("per")
public PermissionCheckServiceImpl permissionCheckServiceImpl(){
return new PermissionCheckServiceImpl();
}
/**
* 配置安全过滤器链
* @param httpSecurity
* @return
* @throws Exception
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sessionManager-> sessionManager.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(