SpringBoot Security 集成JWT实现接口可信赖认证(下)

简介: SpringBoot Security 集成JWT实现接口可信赖认证

create Token方法使用jjwt库创建JWT令牌。用户名就是有效负载的主题。它是使用属性文件中的密钥签名的,并且令牌的有效性也在属性文件中指定。结果令牌将具有Header.Payload.Signature的格式。标头包含类型(JSON Web令牌)和哈希算法(HMAC SHA256)。有效负载又称包含令牌的主题(子),数字日期值(exp)中的到期日期,发布JWT的时间(iat),唯一的JWT标识符(jti)以及由冒号分隔的特定于应用程序的键值对。签名是使用嵌入在应用程序中的密钥的标头和有效负载的哈希值。

配置文件修改
security.jwt.token.secret-key=jwt-token-secret-key-for-encryption
security.jwt.token.expiration=1200000
开发web filter
package com.example.demo.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Base64;
import java.util.Date;
import java.util.Optional;
import java.util.function.Function;
/**
* @author 小隐乐乐
* @since 2020/11/8 20:46
*/
public class JwtTokenFilter extends GenericFilterBean {
   private String secret;
   private static final String BEARER = "Bearer";
   private UserDetailsService userDetailsService;
   public JwtTokenFilter(UserDetailsService userDetailsService, String secret) {
       this.userDetailsService = userDetailsService;
       this.secret = Base64.getEncoder().encodeToString(secret.getBytes());
  }
   @Override
   public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
           throws IOException, ServletException {
       String headerValue = ((HttpServletRequest) req).getHeader("Authorization");
       getBearerToken(headerValue).ifPresent(token -> {
           String username = getClaimFromTokenS((String) token, Claims::getSubject);
           UserDetails userDetails = userDetailsService.loadUserByUsername(username);
           if (username.equals(userDetails.getUsername()) && !isJwtExpired((String) token)) {
               UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                       new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
               usernamePasswordAuthenticationToken.setDetails(
                       new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) req));
               SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
          }
      });
       filterChain.doFilter(req, res);
  }
   private Optional getBearerToken(String headerVal) {
       if (headerVal != null && headerVal.startsWith(BEARER)) {
           return Optional.of(headerVal.replace(BEARER, "").trim());
      }
       return Optional.empty();
  }
   private Date getClaimFromToken(String token, Function<Claims, Date> claimsResolver) {
       final Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
       return claimsResolver.apply(claims);
  }
   private String getClaimFromTokenS(String token, Function<Claims, String> claimsResolver) {
       final Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
       return claimsResolver.apply(claims);
  }
   private boolean isJwtExpired(String token) {
       Date expirationDate = getClaimFromToken(token, Claims::getExpiration);
       return expirationDate.before(new Date());
  }
}

这与Java EE中的Web过滤器相同。此Web筛选器检查令牌是否已过期(即Jwt已过期)。它解析有效负载,获取来自令牌的Claims。它将剥离承载字符串,该字符串是授权标头的值。如果令牌通过了所有检查,则do Filter方法将配置Spring安全性以在上下文中手动设置身份验证。我们指定当前用户已通过身份验证,以使其成功通过。

接下来是在Web安全配置类中添加一些行。

WebSecurityConfiguration改造
package com.example.demo.config;
import com.example.demo.jwt.JwtTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author 小隐乐乐
* @since 2020/11/8 20:20
*/
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
   @Value("${security.jwt.token.secret-key}")
   private String secret;
   @Autowired
   private UserDetailsService userDetailsService;
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http
              .csrf().disable()
              .authorizeRequests()
              .antMatchers("/api/signin").permitAll()
              .anyRequest().authenticated()
              .and()
              .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
       http.addFilterBefore(new JwtTokenFilter(userDetailsService, secret), UsernamePasswordAuthenticationFilter.class);
  }
   @Bean
   @Override
   public AuthenticationManager authenticationManagerBean() throws Exception {
       return super.authenticationManagerBean();
  }
   @Bean
   @Override
   public UserDetailsService userDetailsService() {
       UserDetails user = User.withDefaultPasswordEncoder()
              .username("user")
              .password("password")
              .roles("USER")
              .build();
       return new InMemoryUserDetailsManager(user);
  }
}
接口类改造
package com.example.demo.controller;
import com.example.demo.dto.SigninDto;
import com.example.demo.jwt.JwtProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* @author 小隐乐乐
* @since 2020/11/8 19:44
*/
@RestController
@RequestMapping("/api")
public class HelloController {
   @Autowired
   private JwtProvider jwtProvider;
   @Autowired
   private AuthenticationManager authenticationManager;
   @GetMapping("/hello")
   public String hello() {
       return "hello guys";
  }
   @PostMapping("/signin")
   public String signIn(@RequestBody @Valid SigninDto signInDto) {
       try {
           authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(signInDto.getUsername(), signInDto.getPassword()));
           return jwtProvider.createToken(signInDto.getUsername());
      } catch (AuthenticationException e) {
           System.out.println("Log in failed for user, " + signInDto.getUsername());
      }
       return "";
  }
}
测试应用
signin接口调用获取tokenimage.pnghello接口调用携带token

image.png

总结

Spring Boot Security和JWT Hello World示例已完成。总而言之,当登录身份验证通过时,我们将创建一个JSON Web令牌并将其返回给调用方。然后,调用方将JWT放置在标头中,并在其后续的GET请求中使用授权密钥。Web过滤器检查令牌的有效性。如果有效,Web过滤器将使其通过过滤器链并返回“ Hello world”。

目录
相关文章
|
4月前
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
971 5
|
3月前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
1385 13
|
3月前
|
XML JavaScript Java
SpringBoot集成Shiro权限+Jwt认证
本文主要描述如何快速基于SpringBoot 2.5.X版本集成Shiro+JWT框架,让大家快速实现无状态登陆和接口权限认证主体框架,具体业务细节未实现,大家按照实际项目补充。
216 11
|
5月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
153 8
|
5月前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
137 0
|
Java 应用服务中间件
SpringBoot集成使用jsp(超详细)
SpringBoot集成使用jsp(超详细)
SpringBoot集成使用jsp(超详细)
|
1天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的旅游景区管理系统源码+运行
该项目是基于Java+Springboot+Vue开发的旅游景区管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的旅游景区管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习
26 4
基于Java+Springboot+Vue开发的旅游景区管理系统源码+运行
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
|
3月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
3月前
|
JavaScript 搜索推荐 Java
基于SpringBoot+Vue实现的家乡特色推荐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!

热门文章

最新文章

下一篇
oss创建bucket