Spring Security permitAll 不适用于某些端点

Posted

技术标签:

【中文标题】Spring Security permitAll 不适用于某些端点【英文标题】:Spring Security's permitAll doesn't work for certain endpoints 【发布时间】:2019-03-08 22:56:53 【问题描述】:

我有

@Configuration
@EnableWebSecurity

public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(final HttpSecurity http) throws Exception 
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/api/v1/account/import").permitAll()
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    

我希望所有用户都可以访问/api/v1/account/import 而无需任何 JWT 令牌检查。对于所有其他端点,我希望在 JWTAuthenticationFilter 类中进行 JWT 令牌检查。我尝试了许多不同的场景,但都失败了。我总是联系JWTAuthenticationFilter。如果我去/api/v1/account/import,我不想去JWTAuthenticationFilter

我的控制器:

@RestController
@RequestMapping(value = "/api/v1/account")
public class AccountController 

    private final AccountService accountService;

    public AccountController(final AccountService accountService) 
        this.accountService = accountService;
    

    @PostMapping(path = "/import")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public String importAccount(@Valid @RequestBody final ImportAccountDto importAccountDto) 
        return this.accountService.importAccount(importAccountDto);
    

我的 JWT 过滤器:

public class JWTAuthenticationFilter extends GenericFilterBean 

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain filterChain) throws IOException, ServletException 

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        final String token = request.getHeader("Authorization");

        final JJWTService jjwtService = new JJWTService();

        if (token == null || !jjwtService.parseJWTToken(token)) 
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
         else 
            filterChain.doFilter(req, res);
        
    

我的测试:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class AccountIT 

    @Autowired
    MockMvc mockMvc;

    @Autowired
    private AccountRepository accountRepository;

    @Test
    public void importAccount() throws Exception 

        this.mockMvc.perform(post("/api/v1/account/import")
                .contentType(MediaType.APPLICATION_JSON)
                .content(toJson(importAccountDto)))
                .andExpect(status().isAccepted())
                .andReturn();
    

【问题讨论】:

【参考方案1】:

试试这个

if (!request.getRequestURI().contains("/api/v1/account/import")) 
    final JJWTService jjwtService = new JJWTService();

    if (token == null || !jjwtService.parseJWTToken(token)) 
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
     else 
        filterChain.doFilter(req, res);
    

【讨论】:

以上是关于Spring Security permitAll 不适用于某些端点的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security Oauth2 permitAll()方法小记

Spring Security permitAll 不适用于某些端点

升级到 Spring Boot 2.0.2 后 Spring Security .permitAll() 不再有效

Spring Security - permitAll() 不允许未经身份验证的访问

PermitAll 在 Spring Security 中不起作用

Spring Security permitAll Unauthorized