我已经实现了JWT身份验证和授权。除了未经授权的情况之外,一切都正常运行
未经授权的情况:对路由进行http调用而未提供授权令牌。
结果:禁止403,而不是未经授权
这是我的代码:
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
之后
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
执行,响应为403
这是我的全部课程:
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// setting the user in the security context
String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes()))
.build()
.verify(token.replace(TOKEN_PREFIX, ""))
.getSubject();
if(user != null){
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
备注:
我在 UsernamePasswordAuthenticationFilter 上遇到了同样的问题,我通过覆盖默认的authenticationFailureHandler来解决了这个问题:
setAuthenticationFailureHandler(new JWTAuthenticationFailureHandler());
如何获取正确的401响应代码和正文?
谢谢!
答案 0 :(得分:2)
如果您查看认证失败时要用BasicAuthenticationFilter
覆盖的JWTAuthorizationFilter
会做什么,它将调用authenticationEntryPoint.commence(request, response, failed)
并发送401
BasicAuthenticationEntryPoint
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
但是您有被覆盖并返回null的行为。因此,请尝试以下操作之一:
BadCredentialsException
放回您要返回null的位置response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());