Spring boot 使用Hydra OAuth 2.0配置Spring安全性
我用我的Spring Boot应用程序配置了一个Hydra实例。我刚刚使用注释Spring boot 使用Hydra OAuth 2.0配置Spring安全性,spring-boot,oauth-2.0,spring-security-oauth2,Spring Boot,Oauth 2.0,Spring Security Oauth2,我用我的Spring Boot应用程序配置了一个Hydra实例。我刚刚使用注释@EnableResourceServer将我的应用程序配置为资源服务器。因此,当我在请求中使用承载授权头时,Spring使用我在属性中指定的值: security.oauth2.resource.user-info-uri=... 验证令牌是否有效。不幸的是,我在Hydra OAuth 2.0(/)中找不到这个URL是什么首先:在Ory Hydra中配置您的资源服务器(您必须使用客户端凭据和作用域“Hydra.in
@EnableResourceServer
将我的应用程序配置为资源服务器。因此,当我在请求中使用承载授权头时,Spring使用我在属性中指定的值:
security.oauth2.resource.user-info-uri=...
验证令牌是否有效。不幸的是,我在Hydra OAuth 2.0(/)中找不到这个URL是什么首先:在Ory Hydra中配置您的资源服务器(您必须使用客户端凭据和作用域“Hydra.introspect”将其添加到Ory Hydra,以便能够请求令牌有效性): 第二:添加一个策略,让您的资源服务器请求令牌有效性
$> hydra policies create --skip-tls-verify \
--actions introspect \
--description "Policy to introspect tokens from my api" \
--allow \
--id accesstoken_introsp-policy \
--resources "rn:hydra:oauth2:tokens" \
--subjects my-rest-api
第三:在build.gradle中添加oauth2依赖项(如果是maven,则添加pom.xml):
编撰
'org.springframework.security.oauth:spring-security-oauth2:2.2.1.RELEASE'
第四:配置application.yml以使用Hydra内省端点获取令牌信息
security:
user:
password: none
oauth2:
resource:
token-info-uri: https://yourserver.com/oauth2/introspect
client:
client-id: my-rest-api
client-secret: mypwd
scope: [ "hydra.introspect" ]
第五:创建一个类来配置受访问令牌保护的URL
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private RemoteTokenServices tokenServices;
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/api/v1/**").access("#oauth2.hasScope('my.desired.scope')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(clientId);
tokenServices.setAccessTokenConverter(new OryHydraAccessTokenConverter());
resources.tokenServices(tokenServices);
}
}
class OryHydraAccessTokenConverter extends DefaultAccessTokenConverter {
@Override
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
OAuth2Authentication oAuth2Authentication = super.extractAuthentication(map);
oAuth2Authentication.setDetails(map.get("ext"));
return oAuth2Authentication;
}
}
最后一步:现在,在控制器中,您可以自动连线为参数Oauth2Authentication对象
@GetMapping("/api/v1/data")
public MyBean findDataById(OAuth2Authentication auth,
@RequestParam("id") String id) {
OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) auth.getDetails();
Map<String, Object> ext = (Map<String, Object>) oAuth2AuthenticationDetails.getDecodedDetails();
return MyBean.builder().name("Name:"+ext.get("custom_prop1")).build();
}
@GetMapping(“/api/v1/data”)
公共MyBean findDataById(OAuth2Authentication auth,
@RequestParam(“id”)字符串id){
OAuth2AuthenticationDetails OAuth2AuthenticationDetails=(OAuth2AuthenticationDetails)auth.getDetails();
Map ext=(Map)oAuth2AuthenticationDetails.getDecodedDetails();
返回MyBean.builder().name(“name:+ext.get(“custom_prop1”)).build();
}
在与Hydra团队交谈后,他们完全遵循OAuth2规范,但大多数库都倾向于围绕主要的OAuth2提供商(如Google)进行设计。因此,Spring除了一个GET API和Hydra之外,还提供了一个POST API。您是否有一个github演示项目来实现上述功能?
{
"active": true,
"scope": "my.desired.scope",
"client_id": "my-mobile-app",
"sub": "123121e",
"exp": 1520948372,
"iat": 1520944772,
"iss": "https://yourserver.com",
"ext": {
"custom_prop1": 12321,
"custom_prop2": "Name Surname",
"custom_prop3": false
}
}
@GetMapping("/api/v1/data")
public MyBean findDataById(OAuth2Authentication auth,
@RequestParam("id") String id) {
OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) auth.getDetails();
Map<String, Object> ext = (Map<String, Object>) oAuth2AuthenticationDetails.getDecodedDetails();
return MyBean.builder().name("Name:"+ext.get("custom_prop1")).build();
}