Spring Security OAuth2 的 WebSecurityConfigurerAdapter 与 ResourceServerConfigurerAdapter

WebSecurityConfigurer 是 springsecurity 框架配置的类

ResourceServerConfigurerAdapter 是 oauth2 框架配置的类

1、Spring Security的配置

Java在正常servelet处理http的请求可能会经过很多的filter,大体例子像下面这个:

而spring security又是怎么处理的呢,详见下图:

从图中可以看出spring security自己有一个叫 FilterChainProxy 代理类,该类也实现了 servlet 接口。FilterChainProxy 内部有一个 List filterChains,而 SecurityFilterChain 是一个接口也是一个 chain,每个chain里有若干个 filter,既然有多个filter chain,那么来了一个http请求,这个请求(通过该请求的url来判断)应该由哪个或者哪些 filter chain 来进行处理呢?
在spring security里一个请求只会被一个filter chain进行处理,也就是 spring security 通过遍历 Filter Chains这个集合时,只要找到能处理该请求的 filter chain 就不再进行其他的 filter chain 匹配。

如下图:

比如来了一个请求,url是:/foo/**,那么他会被会第一个filter chain处理,后面的两个filter chain会被忽略掉。`

当我们在 spring boot 引入了spring-security 的相关包时,security默认会为我们创建一个默认 WebSecurityConfigurerAdapter,他拦截所有的http请求 (/**),且这个Order的值是:@Order(100) ,order值越小过滤链越在前。Security默认还会为我们创建一些filter:

每个filter的作用可以在spring security中文档中找到。

当然你可以通过配置文件设置 security.basic.enabled=false 来让默认的失效,或者你可以自定义一个并添加@Order 值更低的 WebSecurityConfigurerAdapter (or WebSecurityConfigurer) 的`@Bean``

比如像下面的代码:

@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)

public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {

 @Override

 protected void configure(HttpSecurity http) throws Exception {

 http.antMatcher("/foo/**")

 ...;

 }

}

2、ResourceServerConfigurer的配置

如果同时在处理同一个Url(如:/api/**)应该是哪个生效?

WebSecurityConfigurerAdapter与ResourceServerConfigurerAdapter同时在的话且都配置了处理url为:/api/**,默认是后者会生效。我们在写ResourceServerConfigurerAdapter时,基本上会这么写:

为什么是后者生效呢,因为默认的WebSecurityConfigurerAdapter里的@Order值是100(我们可以在该类上可以明确看到@Order(100)),而我们在ResourceServerConfigurerAdapter上添加了 @EnableResourceServer 注解,这个玩意儿是干什么用的呢?他其中之一就是定义了@Order值为3(该注解里引用了ResourceServerConfiguration,这个类里面定义了Order值)。

在spring 的体系里Order值越小优先级越高,所以ResourceServerConfigurerAdapter优先级比另外一个更高,他会优先处理,而WebSecurityConfigurerAdapter会失效。

如果我们想让WebSecurityConfigurerAdapter比ResourceServerConfigurerAdapter优先级高的话,只须要让前者的@Order值比后者的@Order值更低就行了。

 

注意:我们每声明一个*Adapter类,都会产生一个 filterChain。前面我们讲到一个request(匹配url)只能被一个filterChain处理,这就解释了为什么二者Adapter同时在的时候,前者默认为什么会失效的原因。我们可以在FilterChainProxy中的getFilters(HttpServletRequest request)方法中可以看到有哪些filter chain,并处理哪些url,例如:

如果我们通过下面这种方式配置的话,requestMatcher值为显示No fields to display:

如果通过这种方式配置的话,requestMatcher值为显示match到的url :/aa/**

3、之间的关系

他们所属的功能模块不同,前者spring security的,后者是spring security oauth2里的。他们都是Adapter,他们都会产生一个filter Chain,他们两者可以相互配合来对不同的Url进行权限控制。

但是,我们经常在写代码的时候经常会出现这种情况,当我们在做oauth2的时候,当把两个类同时放在项目的时候,都声明了对http url的不同处理,但是就是ResourceServerConfigurerAdapter会把的http配置信息完全被覆盖掉,最后形成了,所有的请求只会在 ResourceServerConfigurerAdapter 的 fitler chain中处理,导致用户不知道这两者到底是怎么回事。

这其实是因为对spring security的配置不熟悉导致的,也就是antMatcher() 和 authorizeRequests().antMatchers()

4、例子

只会拦截匹配到/user/**的请求,其他请求会被其他拦截器拦截

拦截所有请求,/api/* 需要有权限,其他地址都放行

上面这个例子,本意是想/api/ 端点须要被认证且要有USER权限;/user/**的端点须要被认证,

但是最终的结果是WebSecurityConfigurerAdapter相关的配置信息没生效。
因为ResourceServerConfigurer的优先级高,请求被它的过滤链所拦截
导致/user/**的接口会被放行

但是如果这么配置:

/api/**会被ResourceServerConfigurer拦截
/user/**会被WebSecurityConfigurer拦截
这样才是对的

5、antMatcher与authorizeRequests

antMatcher()是HttpSecurity的一个方法,他只告诉了Spring我只配置了一个我这个Adapter能处理哪个的url,它与authorizeRequests()没有任何关系。
然后使用 authorizeRequests().antMatchers() 是告诉你在 antMatchers()中指定的一个或多个路径,比如执行permitAll()或hasRole()。他们在第一个http.antMatcher()匹配时就会生效。
所以,WebSecurityConfigurerAdapter 与 ResourceServerConfigurerAdapter 同时使用,其实和spring security的多个HttpSecurity配置是一样的,原理也差不多是一样的。

 

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,我是AI语言模型,无法上传代码,但是我可以给你提供一个简单的Spring Security OAuth2实现认证的步骤: 1. 添加依赖 在pom.xml中添加以下依赖: ```xml <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.4.1</version> </dependency> ``` 2. 配置OAuth2认证服务器 创建一个OAuth2认证服务器的配置类,并实现AuthorizationServerConfigurer接口。在configure(ClientDetailsServiceConfigurer clients)方法中配置客户端详情服务,包括client_id, client_secret, authorized_grant_types, scopes等信息。 ```java @Configuration @EnableAuthorizationServer public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService); } } ``` 3. 配置资源服务器 创建一个资源服务器的配置类,并实现ResourceServerConfigurer接口。在configure(HttpSecurity http)方法中配置资源服务器的安全策略,包括允许访问的URL,需要认证的URL等信息。 ```java @Configuration @EnableResourceServer public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**").authenticated() .anyRequest().permitAll(); } } ``` 4. 配置Spring SecuritySpring Security的配置类中,配置OAuth2的安全策略。在configure(HttpSecurity http)方法中,配置请求的安全策略,包括需要认证的URL,允许访问的URL等信息。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin().loginPage("/login").permitAll() .and() .logout().logoutSuccessUrl("/login").permitAll(); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override @Bean public UserDetailsService userDetailsServiceBean() throws Exception { return super.userDetailsServiceBean(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 以上是Spring Security OAuth2实现认证的简单步骤,具体的代码实现根据自己的需求进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值