从Spring Boot中的JWT安全检查中排除URL



我有一个Spring Boot应用程序,通过将这些依赖项添加到pom.xml中,我用资源服务器来保护它。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency> 

这通常工作得很好,但我需要从安全检查中排除特定的URL,我试图通过创建自定义的WebSecurityConfigurerAdapter来实现这一点。

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring().antMatchers("/test");
}
}

然而,在创建此类之后,所有调用(除了对/test的调用(都将失败,因为服务器重定向到登录页面。

我的端点是这样的:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/")
public class TestController {
@GetMapping("test") // This endpoint should be ignored
public String test() {
return "1.0";
}
@GetMapping("foo")
public String test1() {
return "foo";
}
}

请求时http://localhost:8080/test我的日志输出如下:

2020-08-24 08:48:28.215 DEBUG 7473 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet        : GET "/test", parameters={}
2020-08-24 08:48:28.215 DEBUG 7473 --- [nio-8080-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.test.controllers.TestController#test()
2020-08-24 08:48:28.218 DEBUG 7473 --- [nio-8080-exec-5] m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json]
2020-08-24 08:48:28.218 DEBUG 7473 --- [nio-8080-exec-5] m.m.a.RequestResponseBodyMethodProcessor : Writing ["1.0"]
2020-08-24 08:48:28.219 DEBUG 7473 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

达到终点http://localhost:8080/foo将导致重定向到登录页面,并且根本不会有日志输出。

有人能告诉我我缺了什么吗?如何创建一个除了从安全检查中排除某些URL之外什么都不做的WebSecurityConfigurerAdapter?

请在此处找到一个伪项目:https://github.com/paulsasel/spring-boot-jwt-exclude-urls

如果忽略void configure(final WebSecurity web)中的某些内容,则它将完全省略来自过滤器链的请求。请参阅Spring安全配置-HttpSecurity与WebSecurity

但这只是第一部分。还有另一个重载void configure(HttpSecurity http),它稍后在链中调用,并定义了您希望如何确切地保护端点。如果你不覆盖它,默认值将是formLogin,你可以在souce:中看到它

http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();

这就是它将您重定向到登录页面的原因。

因此,为了使用JWT身份验证,您也应该覆盖后一种身份验证,并定义您希望使用oauth2资源服务器进行身份验证:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}

顺便说一句,在这里您还可以检查角色或请求类型。此外,作为一种替代方法,你也可以忽略这里的/test端点,这对我来说是一个更干净的选择:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.authorizeRequests()
.antMatchers("/test")
.permitAll()
.antMatchers(HttpMethod.GET, "/foo")
.hasAuthority("DUMMYAUTHORITY")
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}

Br,Nandor

最新更新