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未经授权的错误。
上一篇:公司设早鸟晚鸟奖:真的可以提升工作效率吗?|全球热头条
下一篇:最后一页
JWT(JSONWebToken)是一种用于在网络中传输安全信息的开放标准(RFC7519)。它可以在各个服务之间安全...
1、你的数据好像有点问题,20%~30%的数据是几分呢?A列是你的数据在B1中输入下面公式,输入完成后按shift+
1、楼主你新手吧,这是LOL里面的术语,既是:ADC:远程纯物理输出。2、如~冒险者,也叫EZ。3、法外狂徒,也叫男
近日,一网友在微博上爆料称,杭州某公司实施了一种“早鸟奖”和“晚鸟奖”的奖励制度,引发网友热议。...
写字楼刚交付就来了多个大买家
鲁能VS武汉三镇首发浮现:王牌双腰坐镇,莫伊塞斯领衔,郭田雨冲锋
“奶奶,我想吃冰淇淋。”“好,买一个,你们分着吃!”今天,家住附近的周阿婆带着孙子,与邻居爷孙一...
1、precipitation英[prɪˌsɪpɪˈteɪʃn]美[prɪˌsɪpɪˈteʃən]n 匆促;沉淀;(雨等)降落;
1、现象:显示有打印文档,但迟迟不见有打印。2、原因:是输出端口的问题。3、解决方法:删除本地打印机...
1、烘鞋器能烘湿鞋子,烘鞋器本就是专门为烘干鞋子而设计的小家电,具有烘干、杀菌、除臭等功能,适用各...
世界农化网中文网报道:据初步统计,2022年全国小麦病虫害累计发生4,166万hm2次,累计防治7,148万hm2次...
核心提示站在特色小镇风口,小镇到底要怎么做?最大的难点是什么?本文分享整理关于特色小镇的一些观点...
近年来,白银市会宁县按照“脱贫抓产业、产业抓覆盖、覆盖抓达标、达标抓效益”的思路,大力发展“1+N”...
[本站新车上市]日前,我们从官方获悉获,一汽-大众2023款揽境正式上市,新车提供两个排量6款车型,售价...
[本站新车上市]日前,我们从官方获悉获,一汽-大众2023款揽境正式上市,新车提供两个排量6款车型,售价...
4月7日,由中科院计算机网络信息中心主办、中科院广州生物医药与健康研究院(以下简称广州健康院)承办...
“67秒,冠军产生!”4月7日上午,浙江省常山县辉埠小学在操场上举行了一场别开生面的憋气大赛,这也标...
新复航航线具体航班计划为:上海浦东-东京成田(CZ8309 8310),去程北京时间09:20从上海浦东机场起飞,...
集聚直播电商人才、加大直播电商实操培训、精准实施“订单式”培训……这是洛报融媒记者从日前印发的《...
直播吧4月7日讯据《利物浦回声报》援引德媒《鲁尔信息报》报道,贝林厄姆将很快对未来做出决定。《鲁尔...
直播吧4月7日讯据西班牙媒体Relevo消息,皇马想要维持目前球队的中场组成,并与莫德里奇、克罗斯再续约...
1、希拉里·哈恩是21世纪美国涌现的新一代天才小提琴演奏家。2、今年27岁的哈恩,毕业于美国寇蒂斯音乐...
北京时间4月8日21:30,2022-23赛季德甲联赛第27轮,拜仁将在客战挑战弗赖堡。赛前,拜仁主帅图赫尔出席...
1、公司以实现少年人的梦想为理由让其进行包装。2、然后通过明星的专辑、周边、广告、演唱会等等活动抽...
今日消息,博主数码闲聊站透露,小米13Ultra已开始量产,距离正式发布不远了。工业设计上,小米13Ultra...
广告
X 关闭
广告
X 关闭