欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用Spring Boot和JWT,打造可靠接口认证的实践教程(下篇)

最编程 2024-07-28 11:17:42
...
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()); } }