【问题标题】:Spring boot 2.0 HttpSecurity auth doesn't work without sent Authorization headerSpring boot 2.0 HttpSecurity auth 在没有发送 Authorization 标头的情况下不起作用
【发布时间】:2018-11-18 07:59:03
【问题描述】:

我在班级WebSecurity extends WebSecurityConfigurerAdapter 中有此安全设置:

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
        .addFilterBefore(corsFilter(), SessionManagementFilter.class)
        .csrf().disable().authorizeRequests()
        .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
        .anyRequest().authenticated()
        .and()
        .addFilter(new JWTAuthenticationFilter(authenticationManager()))
        .addFilter(new JWTAuthorizationFilter(authenticationManager()));
}

JWTAuthenticationFilter:

class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter
{
    private AuthenticationManager authenticationManager;
    private Logger                logger = Logger.getLogger("JWTAuthenticationFilter");

    JWTAuthenticationFilter(AuthenticationManager authenticationManager)
    {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
    throws AuthenticationException
    {
        String username = req.getParameter("username");
        logger.info("Login attempt with username: " + username);

        return authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(username, req.getParameter("password"), new ArrayList<>())
        );
    }

    @Override
    protected void successfulAuthentication(
        HttpServletRequest req,
        HttpServletResponse res,
        FilterChain chain,
        Authentication auth
    )
    {
        String token = Jwts
            .builder()
            .setSubject(((User) auth.getPrincipal()).getUsername())
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SECRET)
            .compact();

        res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
    }
}

JWTAuthorizationFilter:

public class JWTAuthorizationFilter extends BasicAuthenticationFilter
{
    JWTAuthorizationFilter(AuthenticationManager authManager)
    {
        super(authManager);
    }

    @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)
        {
            String user = Jwts
                .parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                .getBody()
                .getSubject();
            if (user != null)
            {
                return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
            }
            return null;
        }
        return null;
    }
}
  • 当我发送 Authorization: Bearer “正确令牌”标头时,它工作正常。
  • 当我发送 Authorization: Bearer "expired token" 标头时,我收到了正确的错误消息。
  • 但如果我不发送标头,它不会阻塞 API 调用,并且我得到的响应没有错误消息。
  • 如果我发送带有随机文本而不是 Bearer 的 Auth 标头,我会收到没有错误消息的响应。

这有什么问题?

【问题讨论】:

  • JWTAuthenticationFilter 是如何实现的。
  • 我用代码更新了问题。
  • 我没有看到任何与使用令牌进行身份验证相关的内容。那么它怎么能起作用呢?您基本上是使用用户名和密码登录,然后提供令牌。您无处读取此过滤器中的令牌?那么您的令牌在哪里被读取并用于身份验证?
  • 再次使用 JWTAuthorizationFilter 类更新,问题可能出在此处。
  • 如果我不发送 Authorization 标头,getAuthentication 将不会被触发。

标签: spring spring-boot authentication spring-security jwt


【解决方案1】:

不是专家,但您可以尝试使用

在特定位置添加过滤器
.addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);

如果有变化请告诉我

【讨论】:

  • JWTAuthenticationFilter 没有第二个参数,加不了。
  • 第二个参数是用于 addFilter 之前,可能是我搞砸了括号
  • 是的,抱歉,我没看到。但是还是不行,我得到了api响应,没有任何错误。
猜你喜欢
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 2018-03-23
  • 2020-04-24
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2020-12-23
相关资源
最近更新 更多