资源服务配置
@EnableResourceServer
注解到一个 @Configuration 配置类上,并且必须使用 ResourceServerConfigurer 这个 配置对象来进行配置(可以选择继承自 ResourceServerConfigurerAdapter 然后覆写其中的方法,参数就是这个 对象的实例),下面是一些可以配置的属性:
ResourceServerSecurityConfigurer中主要包括:
- tokenServices:ResourceServerTokenServices 类的实例,用来实现令牌服务。
- tokenStore:TokenStore类的实例,指定令牌如何访问,与tokenServices配置可选
- resourceId:这个资源服务的ID,这个属性是可选的,但是推荐设置并在授权服务中进行验证。 其他的拓展属性例如
- tokenExtractor 令牌提取器用来提取请求中的令牌。
HttpSecurity配置这个与Spring Security类似:
- 请求匹配器,用来设置需要进行保护的资源路径,默认的情况下是保护资源服务的全部路径。
- 通过http.authorizeRequests()来设置受保护资源的访问规则
- 其他的自定义权限保护规则通过 HttpSecurity 来进行配置。
@EnableResourceServer 注解自动增加了一个类型为 OAuth2AuthenticationProcessingFilter
的过滤器链
编写ResouceServerConfig:
package pers.zhang.security.order.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
/**
* @Author: acton_zhang
* @Date: 2020/3/31 10:28 下午
* @Version 1.0
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//资源名称,必须与服务器配置的一致
public static final String RESOURCE_ID = "res1";
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
.resourceId(RESOURCE_ID)//资源id
.tokenServices(tokenService())//验证令牌的服务
.stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").access("#oauth2.hasScope('all')")//授权范围
.and().csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
验证token:
ResourceServerTokenServices
是组成授权服务的另一半,如果你的授权服务和资源服务在同一个应用程序上的 话,你可以使用 DefaultTokenServices ,这样的话,你就不用考虑关于实现所有必要的接口的一致性问题。如果 你的资源服务器是分离开的,那么你就必须要确保能够有匹配授权服务提供的 ResourceServerTokenServices
,它知道如何对令牌进行解码。
令牌解析方法:
- 使用 DefaultTokenServices 在资源服务器本地配置令牌存储、解码、解析方式
- 使用 RemoteTokenServices 资源服务器通过 HTTP 请求来解码令牌,每次都请求授权服务器端点
/oauth/check_token
使用授权服务的 /oauth/check_token 端点你需要在授权服务将这个端点暴露出去,以便资源服务可以进行访问, 这在咱们授权服务配置中已经提到了,下面是一个例子,在这个例子中,我们在授权服务中配置了 /oauth/check_token
和/oauth/token_key
这两个端点:
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")// /oauth/token_key 安全配置
.checkTokenAccess("permitAll()") // /oauth/check_token 安全配置
}
在资源 服务配置RemoteTokenServices ,在ResouceServerConfig中配置:
//资源服务临牌解析服务
@Bean
public ResourceServerTokenServices tokenService() {
//使用远程服务请求授权服务器token,必须指定校验token的url、client_id,client_secret
RemoteTokenServices service = new RemoteTokenServices();
service.setCheckTokenEndpointUrl("http://localhost:53020/uaa/oauth/check_token");
service.setClientId("c1");
service.setClientSecret("secret");
return service;
}
编写资源:
在controller包下编写OrderController,此controller表示订单资源的访问类:
@RestController
public class OrderController {
@GetMapping("/r1")
@PreAuthorize("hasAnyAuthority('p1')")//拥有p1权限可以访问r1资源
public String r1() {
return "访问资源1";
}
}
添加安全访问控制:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/r/**").authenticated()
.anyRequest().permitAll();
}
}
测试
1、申请令牌
这里我们使用密码方式
2、请求资源
按照oauth2.0协议要求,请求资源需要携带token,如下:
token的参数名称为:Authorization,值为:Bearer token值