JWT
JWT(JSON Web Token)是一种用于在网络中传输安全信息的开放标准(RFC 7519)。它可以在各个服务之间安全地传递用户认证信息,因为它使用数字签名来验证信息的真实性和完整性。
(资料图片仅供参考)
JWT有三个部分,每个部分用点(.)分隔:
Header:通常包含JWT使用的签名算法和令牌类型。Payload:包含有关用户或其他主题的声明信息。声明是有关实体(通常是用户)和其他数据的JSON对象。声明被编码为JSON,然后使用Base64 URL编码。Signature:用于验证消息是否未被篡改并且来自预期的发送者。签名由使用Header中指定的算法和秘钥对Header和Payload进行加密产生。在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未经授权的错误。
关键词:
(责任编辑:黄俊飞)推荐内容
- Spring Boot的安全配置(三)-世界速讯
- 每日热讯!配置Eureka Client
- 环球观速讯丨excel表格日期格式怎么转换
- 焦点速讯:临澧:以文化人 以艺传理 党
- 全球今头条!毕业证号码查询_毕业证号
- 阿里P9下岗再就业-环球今日报
- 酱爆肉丁花样做法_酱爆肉丁
- 三本读者评选的总裁豪门高人气小说,《情
- 看热讯:第三届中国国际消费品博览会首批
- 当前关注:退役公交卖菜 创意让服务更便民
- 王哲林布莱克尼当选周MVP 乔丹-贝尔获最
- 大学生返乡创业新农人点绿成金 我市广袤
- 荥阳市财政局:召开机关党组织书记抓基层
- 大连公积金惠民新“政策包”今起实施
- 美联新材:正坚定推动普鲁士蓝(白)钠离
- 每日动态!【机构调研记录】国海富兰克林
- 每日速递:赛力斯:4月6日融券卖出19.3万
- 好快!大华朱辛庄地块户型图过程稿疑似流
- 今日一美金等于多少日元(2023年4月6日)
- 迅速找回状态!快船后场大将依然是第二阵
- 国家知识产权局赴河北专题调研专利转化等
- 今热点:巴彦淖尔皮卡解禁,城区通行不受
- 当前要闻:铜箔基板4月6日行情查询?A股
- *ST同洲:截至【2023】年【3】月【20】日
- 三维化学: 2022年年度报告摘要-世界聚焦
- 香港恒生指数4月6日(周四)收盘上涨56.6
- 新消息丨安顺:用好“特意性”旅游核心吸
- 鱼儿有了新“产房” 长沙县首次铺设人工
- 安徽省宿州市父子两代38载接力守护烈士墓
- 厚普股份:公司BCC车载固态储氢产业化项
- 观天下!23中信银行金融债01今日发布发行
- 局地阵风10级以上!河南省气象台发布大风
- 2023江淮十校第三次联考试卷及答案各科解
- 番茄种子怎么种_番茄种子种植方法 环球
- 机构投资者“选基”好眼光 胜率和控制回
- 全球今日讯!魔法少女小圆同人 愿望
- 这个清明,我们把大家的留言带到了英烈墓
- 聚焦:品牌服装店3家分店近万元衣物被偷
- 男子酒后回家路上“白捡”一辆山地自行车
- 合成生物产学研用提速 全产业链布局深入
- 法国总统马克龙抵达北京具体详细内容是什
- 每日动态!高考政策重大改革最新规定2022
- 8万买吗?比亚迪海鸥到店:实车首曝 战
- 轻松加愉快!莫兰特15中9&三分6中2砍下23
- 美国总统拜登已批准阿肯色州的重大灾难声
- 今日关注:网易云音乐下载的歌曲图文步骤
- 萨维诺裁缝有限公司(关于萨维诺裁缝有限
- 生物制品板块4月4日涨0.87%,百克生物领
- 黎明之光官网_黎明之光好玩吗
- 埃梅里率维拉豪取9场英超胜利 同期仅次
- 在华外资研发再升级,各地政策密集出台
- 焦点快看:曲突徙薪的故事(曲突徙薪文言
- 要闻:齐鲁银行积极推广运用跨境金融服务
- 快播:这种病高发!珠海部分班级已停课!
- 新能源汽车,“跑”出加速度_通讯
- 上海环境(601200)4月4日主力资金净卖出
- 天天快看点丨scenery可数吗_scenery可数吗
- 比亚迪和吉利,中间隔着两个长城-环球动态
- 世界滚动:示范引领促提升 结对帮扶共发
- 商务部副部长王受文:贸易环境在日趋优化
- 国家知识产权局赴河北专题调研专利转化等
- 今热点:巴彦淖尔皮卡解禁,城区通行不受
- 当前要闻:铜箔基板4月6日行情查询?A股
- *ST同洲:截至【2023】年【3】月【20】日
- 三维化学: 2022年年度报告摘要-世界聚焦
- 香港恒生指数4月6日(周四)收盘上涨56.6
- 新消息丨安顺:用好“特意性”旅游核心吸
- 鱼儿有了新“产房” 长沙县首次铺设人工
- 安徽省宿州市父子两代38载接力守护烈士墓
- 厚普股份:公司BCC车载固态储氢产业化项
- 观天下!23中信银行金融债01今日发布发行
- 局地阵风10级以上!河南省气象台发布大风
- 2023江淮十校第三次联考试卷及答案各科解
- 番茄种子怎么种_番茄种子种植方法 环球
- 机构投资者“选基”好眼光 胜率和控制回
- 全球今日讯!魔法少女小圆同人 愿望
- 这个清明,我们把大家的留言带到了英烈墓
- 聚焦:品牌服装店3家分店近万元衣物被偷
- 男子酒后回家路上“白捡”一辆山地自行车
- 合成生物产学研用提速 全产业链布局深入
- 法国总统马克龙抵达北京具体详细内容是什
- 每日动态!高考政策重大改革最新规定2022
- 8万买吗?比亚迪海鸥到店:实车首曝 战
- 轻松加愉快!莫兰特15中9&三分6中2砍下23
- 美国总统拜登已批准阿肯色州的重大灾难声
- 今日关注:网易云音乐下载的歌曲图文步骤
- 萨维诺裁缝有限公司(关于萨维诺裁缝有限
- 生物制品板块4月4日涨0.87%,百克生物领
- 黎明之光官网_黎明之光好玩吗
- 埃梅里率维拉豪取9场英超胜利 同期仅次
- 在华外资研发再升级,各地政策密集出台
- 焦点快看:曲突徙薪的故事(曲突徙薪文言
- 要闻:齐鲁银行积极推广运用跨境金融服务
- 快播:这种病高发!珠海部分班级已停课!
- 新能源汽车,“跑”出加速度_通讯
- 上海环境(601200)4月4日主力资金净卖出
- 天天快看点丨scenery可数吗_scenery可数吗
- 比亚迪和吉利,中间隔着两个长城-环球动态
- 世界滚动:示范引领促提升 结对帮扶共发
- 商务部副部长王受文:贸易环境在日趋优化
- 注重多元发展 《巫师》《赛博朋克》IP将
- 海上清洁工是什么鸟?海底清洁工是什么鱼
- 599元 酷冷至尊发布GA241游戏显示器:10
- 铁炉堡卖弹药的在哪里_铁炉堡卖弹药
- 山东高速拟转让山高玉禾田城市运营服务49
- 键盘上中间那个点怎么打_键盘上的中间的
- 张婧仪陈星旭_张婧怡-世界热头条
- 沿河县气象台发布雷电黄色预警信号【Ⅲ/
- 打造城市新商街!通州这个“租客村”颜值
- 划重点!2023年海口市医保政策这些内容有
- 英超现主帅执教时间榜 克洛普执教7年居
- “国际爱鸟日”扬州江都公安发出倡议:保
- 全球速讯:脑机交互与人机共融海河实验室
- 美国歌手TAYLOR ALISON SWIFT将在成都
- 债市行情速递丨10年期国债期货主力合约收
- 世界热门:普通高校应用型本科经济与管理
- 沪深两市股票成交额达10000亿元 全球时快讯
- 太平洋金生无忧(少儿版)优缺点整理,父
- 38个签约项目总投资507亿,太原在沪举行
- 当前视点!阿根廷多地纪念马岛战争爆发41