Spring Security несколько antMatchers с подшаблоном requestMatchers - PullRequest
0 голосов
/ 25 октября 2019

У меня есть конфигурация для Spring Security, представленная в этой ссылке

http
    .requestMatchers()
        .antMatchers("/web/**")
        .and()
    .authorizeRequests()
        .antMatchers("/web/initial/**").permitAll()
        .antMatchers("/**").authenticated()
        .and()
    .addFilterBefore(jwtauthFilter, UsernamePasswordAuthenticationFilter.class);

http
    .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.NEVER);

В настоящее время я всегда получаю 403, что означает его аутентификацию с помощью фильтра. Здесь мне нужно отфильтровать все запросы, поступающие на /web/**, кроме шаблонов /web/initial/**. Есть ли способ добиться этого или мне нужно изменить /web/initial/** на какой-то другой шаблон, которого нет в сети? Я уже ссылался на эту ссылку , но requestMatchers() там не использовался.

DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/web/**']
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/web/initial/'; against '/web/**'
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - matched
DEBUG: org.springframework.security.web.FilterChainProxy - /web/initial/ at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /web/initial/ at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG: org.springframework.security.web.context.HttpSessionSecurityContextRepository - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@a8d3a7a2: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@a8d3a7a2: Principal: com.leadwinner.gpms.user.entities.EmployeeEntity@572c5866; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 192.168.0.17; SessionId: 75ADFD778EFFEE25FB2F3020E8043DB5; Not granted any authorities'
DEBUG: org.springframework.security.web.FilterChainProxy - /web/initial/ at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG: org.springframework.security.web.FilterChainProxy - /web/initial/ at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/web/initial/'; against '/logout'
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /web/initial/' doesn't match 'POST /logout
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /web/initial/' doesn't match 'PUT /logout
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
DEBUG: org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /web/initial/' doesn't match 'DELETE /logout
DEBUG: org.springframework.security.web.util.matcher.OrRequestMatcher - No matches found
DEBUG: org.springframework.security.web.FilterChainProxy - /web/initial/ at position 5 of 11 in additional filter chain; firing Filter: 'JwtAuthenticationTokenFilter'
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Request URL/gpms/web/initial/
DEBUG: org.springframework.security.web.header.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@67494a33
DEBUG: org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed


JwtAuthenticationFilter

package com.leadwinner.sms.config.jwt;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.leadwinner.sms.CustomExceptionHandler;
import com.leadwinner.sms.SessionInfo;

import io.jsonwebtoken.ExpiredJwtException;
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private CustomExceptionHandler customExceptionHandler;

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Autowired
    private SessionInfo sessionInfo;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String header = request.getHeader("Authorization");
        if (header != null && header.startsWith("Bearer ")) {
            String authToken = header.substring(7);

            try {
                String username = jwtTokenUtil.getUsernameFromToken(authToken);

                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null
                        && username.equals(sessionInfo.getBaseEmployeeId())) {
                    if (jwtTokenUtil.validateToken(authToken, username)
                            && username.equals(sessionInfo.getBaseEmployeeId())) {
                        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = 
                                new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
                        usernamePasswordAuthenticationToken
                                .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                    }
                }
                chain.doFilter(request, response);
            } catch (ExpiredJwtException e) {
                System.out.println("Unable to get JWT Token, possibly expired");
                customExceptionHandler.jwtTokenAuthFailedException(request, response, e);
                redirectStrategy.sendRedirect(request, response, "/login");
            } catch (Exception e) {
                redirectStrategy.sendRedirect(request, response, "/login");
                System.out.println("Other exception");
            }
        }
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }

    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }
}

1 Ответ

0 голосов
/ 25 октября 2019

Из вашей конфигурации вы не должны получить 403 для /web/initial/**

Ваша конфигурация

.antMatchers("/web/initial/**").permitAll()
.antMatchers("/**").authenticated()

Здесь FilterSecurityInterceptor пытается сопоставить
путь запрошенного URL-адреса PathWithinApplication против настроенный шаблон муравья в порядке их настройки (первое совпадение выигрывает)

По мере поступления .antMatchers("/web/initial/**").permitAll()Сначала он выигрывает.

Приходите к вашей проблеме 403 (Запрещено) для /web/initial/**. Проверьте свою логику jwtauthFilter.


Пример пояснения для демонстрации первого совпадения выигрыша antMatcher "/app/admin/**" необходимо ROLE_ADMIN, но /app/admin/app-config разрешено первым
http
    .authorizeRequests()
        .antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
        .antMatchers("/app/admin/app-config").permitAll()
        .antMatchers("/app/admin/**").hasRole("ADMIN")
        .antMatchers("/app/user/**").hasAnyRole("ADMIN", "USER")

Запрос http://localhost:8080/sec-project/app/admin/app-configбез входа в систему (не прошедший проверку подлинности пользователя) приводит к появлению следующих журналов. Вы можете заметить, что используется и используется атрибут allowAll и предоставляется ROLE_ANONYMOUS для не прошедшего проверку пользователя.

DEBUG - /app/admin/app-config at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
DEBUG - Checking match of request : '/app/admin/app-config'; against '/resources/**' 
DEBUG - Checking match of request : '/app/admin/app-config'; against '/' 
DEBUG - Checking match of request : '/app/admin/app-config'; against '/login' 
DEBUG - Checking match of request : '/app/admin/app-config'; against '/api/**' 
DEBUG - Checking match of request : '/app/admin/app-config'; against '/app/admin/app-config' 
DEBUG - Secure object: FilterInvocation: URL: /app/admin/app-config; Attributes: [permitAll] 
DEBUG - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@511cd205: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 696171A944493ACA1A0F7D560D93D42B; Granted Authorities: ROLE_ANONYMOUS 
DEBUG - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6df827bf, returned: 1 
DEBUG - Authorization successful 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...