首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring安全BasicAuthenticationFilter返回403而不是401

Spring安全BasicAuthenticationFilter返回403而不是401
EN

Stack Overflow用户
提问于 2020-06-24 19:24:35
回答 1查看 1.3K关注 0票数 3

我已经实现了JWT身份验证和授权。除了未经授权的情况外,一切都很正常。

未经授权的场景:在不提供授权令牌的情况下对路由进行http调用。

结果:403被禁止而不是未经授权

这是我的代码:

代码语言:javascript
复制
@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);
}

代码语言:javascript
复制
    if (header == null || !header.startsWith(TOKEN_PREFIX)) {
        chain.doFilter(req, res);
        return;
    } 

执行,响应为403。

这是我的全班:

代码语言:javascript
复制
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来解决这个问题:

代码语言:javascript
复制
setAuthenticationFailureHandler(new JWTAuthenticationFailureHandler());

如何才能得到正确的401响应代码和正文?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2020-06-25 06:35:10

如果您查看当身份验证失败时使用BasicAuthenticationFilter重写JWTAuthorizationFilter所做的事情,它将调用发送401的authenticationEntryPoint.commence(request, response, failed)

BasicAuthenticationEntryPoint

代码语言:javascript
复制
    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的行为。因此,请尝试以下方法之一,而不是这样:

返回空response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());

  • 抛出BadCredentialsException
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62562633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档