一、前言

   Spring Security OAuth2要用到WebSecurityConfigurerAdapter和 OAuth2的资源管理服务配置url的保护规则,所以需要了解关于他们保护规则的一些配置规则,Spring Security是spring security提供的功能,而OAuth2资源管理服务是Spring security OAuth2提供的功能,本质上都是保护api,其实就是通过spring 的过滤器来达到url的安全访问控制。

二、Spring Security 可以为 url 设置各种访问规则,比如:

http.authorizeRequests().antMatchers("/api/**").denyAll();    //拒绝访问

http.authorizeRequests().antMatchers("/api/**").authenticated();    //需认证通过

http.authorizeRequests().antMatchers("/api/**").permitAll();    //无条件允许访问

 

其它 
//hello 进行匹配,不管HTTP METHOD是什么
 //http.authorizeRequests().antMatchers("/v1/hello").hasRole("USER");

//表示所有的get请求都不需要权限认证
        //http.authorizeRequests().antMatchers(HttpMethod.GET).access("permitAll");

//匹配/hello,且http method是POST,需要权限认证
        //http.authorizeRequests().antMatchers(HttpMethod.POST, "/v1/world").hasRole("USER");

//匹配 /hello,且http method是GET,不需要权限认证
        //http.authorizeRequests().antMatchers(HttpMethod.GET, "/v1/hello").access("permitAll");

//其他例子2

 http
                  .authorizeRequests()            1                                                   
                        .antMatchers( "/resources/**", "/signup" , "/about").permitAll()  2
                        .antMatchers( "/admin/**").hasRole("ADMIN" )                    3    
                        .antMatchers( "/db/**").access("hasRole('ADMIN') and hasRole('DBA')")  4
                        .anyRequest().authenticated()        5
                                         
                        .and()

三、Spring security 规则执行的原理

1.spring security会把这些规则按先后顺序放到一个ArrayList<UrlMapping>的集合中,先注册的规则放前面,后注册的放后面,然后它会这个集合中遍历一遍放入一个map中,把url的RequestMatcher为key,以denyAll,authenticated,permitAll等为值放进LinkedHashMap,这个map是最终的规则集合,由于是map所以它会去重处理,即相同的url只会保留一个。这时候对url的权限判断,第一个能匹配上这个url的规则,就最终会执行这个规则,所以当一个url有多个规则时,它会按顺序执行第一个碰到的规则,例如:

  一个url是/api/aaa/bbb时,既可以匹配/**,又可以匹配/api/*,最终会匹配哪一个规则呢?答案是:按注册规则顺序,第一条能匹配收,就执行这个作为最终规则。

2.相同的url的匹配规则,如上面例子中 "/api/**" 一共有三条规则,一个denyAll,一个authenticated,一个permitAll ,最终会匹配哪条规则呢?

答:在 ArrayList 转 LinkedHashMap 时,相同的url 的匹配规则中 后面的会冲掉 前面的, 所以,最终执行的规则会是最后注册的那条。

四、OAuth2资源服务器ResourceServerSecurityConfigurer 请求匹配器如何配置?

例子1:
http.requestMatchers().antMatchers("/api/**")
                .and()
                .authorizeRequests()
                .antMatchers("/api/**").authenticated();


例子2
http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                    .and().authorizeRequests().antMatchers("/free/**").permitAll().and()
                    .authorizeRequests().anyRequest().authenticated()
                    .and().formLogin().permitAll();//必须认证过后才可以访问
        }

总结:

由此可见WebSecurityConfigurerAdapter缺省是高于资源服务器ResourceServerConfigurerAdapter,这2个均需要时,有时候资源服务怕多个,所以对于非/aip/的url地址安全保护放在前者,/api的保护放在后者,WebSecurityConfigurerAdapteri没有必要了。但还是理解一下这2个东西:

二者关系
WebSecurityConfigurerAdapter用于保护oauth相关的endpoints,同时主要作用于用户的登录(form login,Basic auth)
ResourceServerConfigurerAdapter用于保护oauth要开放的资源,同时主要作用于client端以及token的认证(Bearer auth)
因此二者是分工协作的

在WebSecurityConfigurerAdapter不拦截oauth要开放的资源
@Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.requestMatchers().antMatchers("/oauth/**")
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated();
    }
在ResourceServerConfigurerAdapter配置需要token验证的资源
@Override
    public void configure(HttpSecurity http) throws Exception {
        http.requestMatchers().antMatchers("/api/**")
                .and()
                .authorizeRequests()
                .antMatchers("/api/**").authenticated();
    }

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐