Spring boot 2.0 HttpSecurity auth无法在没有发送授权标头的情况下工作

时间:2018-06-08 09:30:22

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

我在课程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;
    }
}
  • 当我发送授权:持票人&#34;正确的令牌&#34;标题,它工作正常。
  • 当我发送授权:Bearer&#34;过期令牌&#34;标题,我收到了正确的错误消息。
  • 但是,如果我没有发送标题,它就不会支持API调用,我收到了没有错误消息的响应。
  • 如果我使用随机文本而不是Bearer发送Auth标头,我收到了没有错误消息的响应。

它可能有什么问题?

1 个答案:

答案 0 :(得分:0)

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

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

如果有变化,请告诉我