wake-up-neo.net

Wie kann ein Federsicherheitsfilter nur an gesicherten Endpunkten angewendet werden?

Ich habe die folgende Spring Security-Konfiguration:

    httpSecurity
            .csrf()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/api/**").fullyAuthenticated()
            .and()
            .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

authenticationTokenFilterBean() wird auch auf Endpunkte angewendet, die nicht mit dem /api/**-Ausdruck übereinstimmen. Ich habe auch versucht, den folgenden Konfigurationscode hinzuzufügen

@Override
public void configure(WebSecurity webSecurity) {
    webSecurity.ignoring().antMatchers("/some_endpoint");
}

aber das hat mein problem immer noch nicht gelöst. Wie kann ich der Fed-Sicherheit sagen, Filter nur auf Endpunkten anzuwenden, die dem gesicherten URI-Ausdruck entsprechen? Vielen Dank

15
Bravo

Wenn Sie den .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); verwenden

Sie können im Konstruktor den spezifischen Pfad definieren, auf den er angewendet wird:

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super("/api/**");
        this.setAuthenticationManager(authenticationManager);
    }

    @Override
    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
        return super.requiresAuthentication(request, response);
    }

Die RequestsAuthentication-Methode wird verwendet, um zu wissen, ob für diesen Endpunkt eine Authentifizierung erforderlich ist

1
Qualaelay

Ich glaube, ich habe einen Weg gefunden, um es zu lösen. Ich habe JwtTokenAuthenticationProcessingFilter was eine AbstractAuthenticationProcessingFilter ist. Ich möchte, dass die Anforderung authentifiziert wird, wenn sich im Kopf ein Token befindet, die Anforderung jedoch nicht blockiert wird, wenn dies fehlgeschlagen ist. Alles, was Sie brauchen, ist, dasdoFilterneu zu schreiben und denchain.doFilteraufzurufen, unabhängig davon, was das Authentifizierungsergebnis ist (das Aufrufen von erfolgloser Authentifizierung ist optional). Hier ist ein Teil meines Codes.

public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {

    private final TokenExtractor tokenExtractor;

    @Autowired
    public JwtTokenAuthenticationProcessingFilter(TokenExtractor tokenExtractor, RequestMatcher matcher) {
        super(matcher);
        this.tokenExtractor = tokenExtractor;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (!this.requiresAuthentication(request, response)) {
            chain.doFilter(request, response);
        } else {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Request is to process authentication");
            }

            boolean success = true;

            Authentication authResult = null;
            try {
                authResult = this.attemptAuthentication(request, response);
            } catch (InternalAuthenticationServiceException var8) {
                this.logger.error("An internal error occurred while trying to authenticate the user.", var8);
                success = false;
            } catch (AuthenticationException var9) {
                success = false;
            }


            if (success && null != authResult) {
                this.successfulAuthentication(request, response, chain, authResult);
            }

            // Please ensure that chain.doFilter(request, response) is invoked upon successful authentication. You want
            // processing of the request to advance to the next filter, because very last one filter
            // FilterSecurityInterceptor#doFilter is responsible to actually invoke method in your controller that is
            // handling requested API resource.
            chain.doFilter(request, response);
        }
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        String tokenPayload = request.getHeader(WebSecurityConfig.AUTHENTICATION_HEADER_NAME);
        RawAccessJwtToken token = new RawAccessJwtToken(tokenExtractor.extract(tokenPayload));
        return getAuthenticationManager().authenticate(new JwtAuthenticationToken(token));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authResult);
        SecurityContextHolder.setContext(context);
    }
}
0
Shengfeng Li