【发布时间】:2020-07-27 13:48:22
【问题描述】:
所以我想问一下有关 JWT 验证的问题。
我的 springboot 项目为除登录和注销端点之外的任何 api 请求实施 jwt 验证。 我的登录和注销端点 (..../api/v1/auth/login, ..../api/v1/auth/logout) 是基于另一个来源的 SSO。 因此,当我使用该 SSO 登录时,他们会将其 JWT 令牌返回到我的后端进程。
然后,当我点击另一个 api 时,我想先用之前生成的 jwt 对其进行验证,但是虽然我的 jwt 匹配,但它总是给出 401 错误。
那么这是我的身份验证类:
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
public class AuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Value("${xxxx.app.client_secret}")
private String clientSecret;
private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);
AuthenticationFilter(final RequestMatcher requiresAuth) {
super(requiresAuth);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
String tokenRequest = httpServletRequest.getHeader("Authorization");
validateJwtToken(tokenRequest.substring(7));
Authentication requestAuthentication = new UsernamePasswordAuthenticationToken(tokenRequest, tokenRequest);
return getAuthenticationManager().authenticate(requestAuthentication);
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(clientSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
在 validateJwtToken 方法中,没有问题,因为它给了我 true 返回,但是当它返回尝试身份验证时,它会在该类中捕获这样的错误
catch (InternalAuthenticationServiceException failed) {
logger.error(
"An internal error occurred while trying to authenticate the user.",
failed);
unsuccessfulAuthentication(request, response, failed);
return;
抱歉我的代码不好,这是我第一次为我的项目实现 jwt 安全性。那么当我遇到这样的情况时该怎么办?谢谢,任何帮助或建议将不胜感激。
【问题讨论】:
标签: java spring-boot authentication jwt single-sign-on