JWT(JSON Web Token)是一种用于在网络中传输安全信息的开放标准(RFC 7519)。它可以在各个服务之间安全地传递用户认证信息,因为它使用数字签名来验证信息的真实性和完整性。
JWT有三个部分,每个部分用点(.)分隔:
【资料图】
在Spring Boot中,您可以使用Spring Security和jjwt库来实现JWT的认证和授权。下面是一个使用JWT的示例:
@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Value("${jwt.secret}") private String jwtSecret; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(HttpMethod.POST, "/api/authenticate").permitAll() .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtSecret)) .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtSecret)) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(new JwtAuthenticationProvider(jwtSecret)); }}
在上面的示例中,SecurityConfig
类继承了WebSecurityConfigurerAdapter
并使用了@EnableWebSecurity
注解启用Spring Security。configure()
方法使用HttpSecurity
对象来配置HTTP请求的安全性。.csrf().disable()
禁用了CSRF保护。.authorizeRequests()
表示进行授权请求。.antMatchers(HttpMethod.POST, "/api/authenticate").permitAll()
表示允许POST请求到/api/authenticate
路径。.anyRequest().authenticated()
表示要求所有其他请求都需要身份验证。.addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtSecret))
和.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtSecret))
分别添加JWT认证和授权过滤器。.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
指定了会话管理策略。
configure()
方法中还有一个configure(AuthenticationManagerBuilder auth)
方法,它使用JwtAuthenticationProvider
类配置身份验证。在这里,jwtSecret
被注入到JwtAuthenticationProvider
构造函数中,以便在认证过程中使用。
下面是JwtAuthenticationFilter
和JwtAuthorizationFilter
的实现:
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; private final String jwtSecret; public JwtAuthenticationFilter(AuthenticationManager authenticationManager, String jwtSecret) { this.authenticationManager = authenticationManager; this.jwtSecret = jwtSecret; setFilterProcessesUrl("/api/authenticate"); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { try { LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequest.class); Authentication authentication = new UsernamePasswordAuthenticationToken( loginRequest.getUsername(), loginRequest.getPassword() ); return authenticationManager.authenticate(authentication); } catch (IOException e) { throw new RuntimeException(e); } } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) { UserPrincipal userPrincipal = (UserPrincipal) authResult.getPrincipal(); String token = Jwts.builder() .setSubject(userPrincipal.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 864000000)) .signWith(SignatureAlgorithm.HS512, jwtSecret) .compact(); response.addHeader("Authorization", "Bearer " + token); }}
JwtAuthenticationFilter
类继承了UsernamePasswordAuthenticationFilter
类,它用于处理基于用户名和密码的身份验证。它还使用AuthenticationManager
来验证用户名和密码是否正确。jwtSecret
在构造函数中被注入,用于生成JWT令牌。
在attemptAuthentication()
方法中,LoginRequest
对象被反序列化为从请求中获取的用户名和密码。这些值被封装到UsernamePasswordAuthenticationToken
中,并传递给AuthenticationManager
以验证用户身份。
在身份验证成功后,successfulAuthentication()
方法被调用。在这里,UserPrincipal
对象被从Authentication
对象中获取,然后使用Jwts
类生成JWT令牌。setSubject()
方法将用户名设置为JWT主题。setIssuedAt()
方法设置JWT令牌的发行时间。setExpiration()
方法设置JWT令牌的到期时间。signWith()
方法使用HS512算法和jwtSecret
密钥对JWT令牌进行签名。最后,JWT令牌被添加到响应标头中。
下面是JwtAuthorizationFilter
的实现:
public class JwtAuthorizationFilter extends BasicAuthenticationFilter { private final String jwtSecret; public JwtAuthorizationFilter(AuthenticationManager authenticationManager, String jwtSecret) { super(authenticationManager); this.jwtSecret = jwtSecret; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String authorizationHeader = request.getHeader("Authorization"); if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) { chain.doFilter(request, response); return; } String token = authorizationHeader.replace("Bearer ", ""); try { Jws claimsJws = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token); String username = claimsJws.getBody().getSubject(); List authorities = (List) claimsJws.getBody().get("authorities"); List grantedAuthorities = authorities.stream() .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, grantedAuthorities); SecurityContextHolder.getContext().setAuthentication(authentication); chain.doFilter(request, response); } catch (JwtException e) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); } }}
JwtAuthorizationFilter
类继承了BasicAuthenticationFilter
类,并覆盖了doFilterInternal()
方法。在这个方法中,请求头中的Authorization
标头被解析,如果它不是以Bearer
开头,则直接传递给过滤器链。否则,从令牌中解析出主题(用户名)和授权信息,然后创建一个包含用户身份验证和授权信息的Authentication
对象,并将其设置到SecurityContextHolder
中。
如果JWT令牌无效,JwtException
将被抛出,并返回HTTP 401未经授权的错误。
JWT(JSONWebToken)是一种用于在网络中传输安全信息的开放标准(RFC7519)。它可以在各个服务之间安全...
e公司讯,4月6日,国资委党委书记、主任张玉卓到中国电子信息产业集团有限公司所属华大九天调研,就中央...
上海生育津贴2023年发放标准是多少?答案是这样的下面跟社保网小编一起来看看具体详情吧。上海生育妇女...
北京时间4月6日凌晨,本赛季英超联赛第25轮补赛上演了一场精彩万分的强强对话。英超传统豪门球队“红...
【2023年更新】常州自考准考证电子照片要求(最新)常州自考准考证打印指南(2023年4月)准考证打印及使用注...
河南经济报记者杨磊通讯员赵娜叶县农商银行一名身患尿毒症的员工,因高额的医疗费用使其本不富裕的家庭...
如何寻找能出资且愿意出资的LP才是破局之道。
津滨海讯(记者范炳菲)4月4日,滨海新区第1期干部学习大讲堂在区委党校举行,天津财经大学马克思主义学...
水利部5日发布汛情通报,受强降雨影响,华南地区10条河流发生超警洪水,水利部门正全力做好洪水防御工作...
抢救、诊疗、手术、观察等功能集成化的空间,大幅缩短患者在不同功能区域转运的时间;独立化的创伤中心...
如何才能更好地实现数据更好地备份?西部数据在世界备份日给你新解答
重制 复刻版的舆论环境向来不算好,“炒冷饭”标签怎么看也不像褒义。当然,玩家们期待创新和改变无可厚非
猛龙客场120-110大胜黄蜂。黄蜂早已无缘季后赛,众多核心缺阵。马勒东、米哈伊柳克、理查兹的发挥帮助黄...
在周二公布的数据显示美国2月职位空缺降至近两年来的最低水平后,市场预计美联储已经结束了加息周期,并...
1、一段名为“对靓颖新专辑《我相信》的终极致敬”的视频在网上传得沸沸扬扬,视频的内容是一位身穿黑白...
怀远县气象局发布大风蓝色预警【IV级 一般】
HKC现已推出新款MG25H显示器,24 5英寸1080p360Hz规格,售价2999元。参数方面,这款显示器采用了24 5英寸的FAST
来源:搜狐体育网1-4!上海申花没有发生奇迹,以一场失利的方式无缘亚冠淘汰赛,目送东京FC携手蔚山现代...
浙江嘉兴:织就一张“收废品但不见废品”的便民回收网
1、筷子一头圆、一头方。圆的象征天,方的象征地,对应天圆地方。这是中国人对世界基本原则的理解。2、...
新华社北京4月4日电 中国外汇交易中心4月4日受权公布人民币对美元、欧元、日元、港元、英镑、澳元、新...
本报3日讯(记者狄婕)3日晚,省森林草原防灭火指挥部召开视频调度会议,贯彻落实全国、全省春季森林草原
4月份是绿色消费季,后面还有国际消费季、暑期消费季、金秋购物节等。北京、天津、河北联手举办京津冀消...
09年春节,我是带着华版以及多位车友交办的油耗测试任务中度过的。现交作业如下,欢迎大家交流、探讨。测...
长沙晚报掌上长沙4月3日讯(全媒体记者宁霞通讯员嵇田利)近日,由长沙县文化旅游广电体育局、长沙县路...
X 关闭
X 关闭