专栏首页朝雨忆轻尘Spring Boot使用JWT实现系统登录验证

Spring Boot使用JWT实现系统登录验证

简介

什么是JWT(Json Web Token)

jwt是为了在网络应用环境间传递声明而执行的一种基于json的开放标准。该token被设计紧凑且安全的,特别适用于SSO场景。 jwt的声明一般被用来在身份提供者和服务提供者之间传递被认证的用户身份信息。

JWT长什么样

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0MDAyIiwiZXhwIjoxNTEwOTcwMjU4fQ._FOqy5l44hODu3DjXh762LNUTLNQH15fdCUerdseDpmSKgkVSCjOyxQNTBKDSh3N-c83_pdEw5t6BdorgRU_kw

JWT的构成

JWT通常由三部分组成,头信息(header)、消息体(body)、签名(signature) 头信息指定了JWT使用的签名算法

header={alg=HS512}

消息体包含了JWT的意图,exp为令牌过期时间

body={sub=testUsername, exp=1510886546}

签名通过私钥生成

signature=kwq8a_B6WMqHOrEi-gFR5rRPmPL7qoShZJn0VFfXpXc1Yfw6BfVrliAP9C4UnXlqD3wRXO3mw_DDIdglN5lH9Q

使用springboot集成jwt

jwt官网

springboot官网

引用依赖

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency>

构建普通rest接口

@RestController @RequestMapping("/employee") public class EmployeeController { @GetMapping("/greeting") public String greeting() { return "Hello,World!"; } }

JwtLoginFilter

public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter { private AuthenticationManager authenticationManager; public JwtLoginFilter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { Employee employee = new Employee(); return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( employee.getUsername(), employee.getPassword(), new ArrayList<>() ) ); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { String token = Jwts.builder() .setSubject(((User) authResult.getPrincipal()).getUsername()) .setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000)) .signWith(SignatureAlgorithm.HS512, "JWTSecret") .compact(); response.addHeader("Authorization", JwtUtils.getTokenHeader(token)); } }

JwtAuthenticationFilter

public class JwtAuthenticationFilter extends BasicAuthenticationFilter { public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String header = request.getHeader("Authorization"); if (header == null || !header.startsWith(JwtUtils.getAuthorizationHeaderPrefix())) { chain.doFilter(request, response); return; } UsernamePasswordAuthenticationToken authenticationToken = getUsernamePasswordAuthenticationToken(header); SecurityContextHolder.getContext().setAuthentication(authenticationToken); chain.doFilter(request, response); } private UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationToken(String token) { String user = Jwts.parser() .setSigningKey("PrivateSecret") .parseClaimsJws(token.replace(JwtUtils.getAuthorizationHeaderPrefix(), "")) .getBody() .getSubject(); if (null != user) { return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); } return null; } }

SecurityConfiguration

@Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { super.configure(web); } @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().csrf().disable().authorizeRequests() .anyRequest().authenticated() .and() .addFilter(new JwtLoginFilter(authenticationManager())) .addFilter(new JwtAuthenticationFilter(authenticationManager())); } }

使用postman测试

首先我们先测试/employee/greeting 响应如下:

{ "timestamp": 1510887634904, "status": 403, "error": "Forbidden", "message": "Access Denied", "path": "/employee/greeting" }

很明显,状态码为403,此刻我们如果先登录拿到token后再测试呢,测试如下

登录成功后,我们可以看到headers中已经带有jwt

authorization →Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0VXNlcm5hbWUiLCJleHAiOjE1MTA4ODkxMDd9.FtdEM0p84ff5CzDcoiQhtm1MF_NfDH2Ij1jspxlTQhuCISIzYdoU40OsFoxam9F1EXeVw2GZdQmArVwMk6HO1A

由于postman在一般情况下不支持自定义header 这个时候我们需要下载一个插件开启interceptor 开启后将authorization 放入header继续测试:

这时我们发现已经成功返回hello,world!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Security OAuth2实现单点登录

    在本教程中,我们将讨论如何使用 Spring Security OAuth 和 Spring Boot 实现 SSO(单点登录)。

    朝雨忆轻尘
  • Java实现动态代理的两种方式

    Java领域中,常用的动态代理实现方式有两种,一种是利用JDK反射机制生成代理,另外一种是使用CGLIB代理。

    朝雨忆轻尘
  • Spring Boot + Spring Cloud 构建微服务系统(二):服务消费和负载(Ribbon)

    在上一篇教程中,我们是这样调用服务的,先通过 LoadBalancerClient 选取出对应的服务,然后使用 RestTemplate 进行远程调用。

    朝雨忆轻尘
  • SpringCloud-Eureka【服务案例】

      上篇文章我们介绍了Eureka的集群环境搭建,本文我们来通过Eureka作为注册中心来实现一个案例,案例结构如下

    用户4919348
  • springboot集成ueditor富文本编辑器(不需修改ueditor源码)

    最近工作需要重新搭建公司网站,其中需要使用富文本编辑器,货比三家,最后选择了百度团队的UEditor。项目框架为springboot,所以涉及到springbo...

    凯哥Java
  • 基于Springboot+Dubbo+Nacos 注解方式实现微服务调用

    今天跟大家分享基于Springboot+Dubbo+Nacos 注解方式实现微服务调用的知识。

    程序员小强
  • Redis的单元测试 - Redis mock

    ps: 为了把文件写对地方,需要在建立test/resources/application.properties空文件

    十毛
  • springboot整合springsecurity框架,在项目里面集成生成公钥和私钥的代码(分布式项目)(四)

    之前我们已经可以使用工具类生成公钥和私钥了。因为我们现在的项目是分布式的项目,所以重新创建一个子项目,在这个子项目里面写我们生成token的代码

    一天不写程序难受
  • SpringBoot整合Ehcache

      本文介绍下SpringBoot整合SpringDataJPA后加入缓存组件Ehcache的操作。

    用户4919348
  • 详细介绍SpringBoot整合SpringSecurity

      本文我们来详细给小伙伴们介绍下SpringBoot整合SpringSecurity的过程,用到的技术为:SpringBoot2.2.1+SpringSecu...

    用户4919348

扫码关注云+社区

领取腾讯云代金券