簡體   English   中英

沒有發送授權標頭,Spring Boot 2.0 HttpSecurity auth將無法正常工作

[英]Spring boot 2.0 HttpSecurity auth doesn't work without sent Authorization header

我在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標頭,則得到的響應沒有錯誤消息。

有什么問題嗎?

不是專家,但是您可以嘗試使用以下方法在特定位置添加過濾器

.addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);

讓我知道是否有什么變化

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM