最新boot-security jwt 实现登录
security
springboot 版本 3.0.4
首先搞一个springBoot 项目
创建maven项目
引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
引入jwt相关
<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.9.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
下面就是就是配置了
创建一个security 配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
}
注意新版的这个不需要继承了,这就就可以了下面就是具体的设置方法
完整代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {
//密码
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
//这里不创建用户 等会注册的时候用来注册
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager(){
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
return inMemoryUserDetailsManager;
}
//自定义的登录成功逻辑
@Resource
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
//自定义的 请求头拦截器 代码在后面
@Resource
private MyTokenFilter myTokenFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(
//创建用户的路径不要鉴权
authorize->authorize.requestMatchers("/user/create").anonymous()
.anyRequest().authenticated())
.csrf(csrf-> csrf.disable())//前后端分离这个地方屏蔽掉
//没有权限的请求
.exceptionHandling(exception->exception.authenticationEntryPoint(new MyAuthenticationEntryPoint()))
.formLogin(login->login
.loginProcessingUrl("/login")
//登录成功处理
.successHandler(myAuthenticationSuccessHandler)
//登录失败处理
.failureHandler(new MyAuthenticationFailureHandler())
.permitAll())
.sessionManagement(session->session
//不使用session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
//token拦截器
.addFilterBefore(myTokenFilter,SessionManagementFilter.class)
.build();
}
}
其他就是常规的一些方法,这里就不介绍了,如果需要可以留言
展示一下token拦截的处理
@Component
@Slf4j
public class MyTokenFilter extends OncePerRequestFilter {
@Resource
private TokenJwt tokenJwt;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String jwt = request.getHeader("Authorization");
if (jwt != null ) {
try {
String userStr = tokenJwt.checkJwt(jwt);
JSONObject obj = JSONObject.parseObject(userStr);
SysUser sysUser = new SysUser();
sysUser.setName(obj.getString("name"));
sysUser.setUserName(obj.getString("sub"));
sysUser.setPhone(obj.getString("phone"));
sysUser.setAuthorities(obj.getJSONArray("roles"));
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(
sysUser, null, sysUser.getAuthorities());
// 授权
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (InvalidJwtException e) {
//验证失败
log.info("{} 验证失败",jwt);
}
}
filterChain.doFilter(request, response);
}
}
jwt 工具类
@Slf4j
@Component
public class TokenJwt {
@Resource
private RsaJsonWebKey rsaJsonWebKey;
private final String HEADER_KEY = "xiZi-token";
public String getJwt(UserDetails userDetails) throws JoseException {
JwtClaims claims = new JwtClaims();
claims.setIssuer("xizi");
claims.setAudience("application user");
claims.setExpirationTimeMinutesInTheFuture(30);
claims.setGeneratedJwtId();
claims.setIssuedAtToNow();
claims.setNotBeforeMinutesInThePast(10);
claims.setSubject(userDetails.getUsername());
claims.setClaim("phone", "");
claims.setClaim("email", "");
claims.setClaim("orgName", "");
claims.setClaim("orgCode", "");
claims.setClaim("regionName", "");
claims.setClaim("regionCode", "");
claims.setClaim("name", "");
claims.setClaim("sex", "");
claims.setStringListClaim("roles", userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(rsaJsonWebKey.getPrivateKey());
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_PSS_USING_SHA256);
return jws.getCompactSerialization();
}
public String checkJwt(String jwt) throws InvalidJwtException {
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setAllowedClockSkewInSeconds(30)
.setRequireSubject()
.setExpectedIssuer("xizi")
.setExpectedAudience("application user")
.setVerificationKey(rsaJsonWebKey.getKey())
.setJwsAlgorithmConstraints(
AlgorithmConstraints.ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_PSS_USING_SHA256)
.build();
try {
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
return jwtClaims.toJson();
} catch (InvalidJwtException e) {
if (e.hasExpired()) {
log.info("jwt 超时");
}
//验证不通过
throw e;
}
}
}
创建用户的逻辑
@Resource
private UserService service;
@Resource
private InMemoryUserDetailsManager inMemoryUserDetailsManager;
@Resource
private PasswordEncoder passwordEncoder;
@PostMapping(value = {"user/create"})
public ResultVo createUser(@RequestBody JSONObject param){
try{
log.info("create user {}",param);
SysUser sysUser = new SysUser();
sysUser.setUserName(param.getString("username"));
sysUser.setName(param.getString("username"));
sysUser.setPassword(passwordEncoder.encode(param.getString("password")));
sysUser.setPhone("*********");
sysUser.setAuthorities(Arrays.asList(new String[]{"ROLE_USER"}));
sysUser.setEnable(true);
sysUser.setAccountNonExpired(true);
sysUser.setAccountNonLocked(true);
sysUser.setCredentialsNonExpired(true);
inMemoryUserDetailsManager.createUser(sysUser);
return ResultVo.ok("创建成功");
}catch (IllegalArgumentException illegalArgumentException){
return ResultVo.error("创建失败");
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/4a75cd99dc61465c9ee1b85a3a17b0e4.png#pic_center)