Sta*_*007 15 spring-security spring-security-oauth2
我们有一个权利数据库,其中包含应用程序ID,角色和用户映射到每个应用程序的角色.遵循线程建议如何基于resourceId将用户角色映射到oauth2范围/权限?
忽略我上面提到的权利数据库,我是否根据下面代码中的user和resourceId将角色"USER","READER","WRITER"映射到oauth2范围/权限?
用户认证/授权配置
@Configuration
@Order(-10)
protected static class LoginConfig extends WebSecurityConfigurerAdapter {
....
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.parentAuthenticationManager(authenticationManager);
// @formatter:off
auth.inMemoryAuthentication()
.withUser("admin").password("admin")
.roles("ADMIN", "USER", "READER", "WRITER")
.and()
.withUser("user").password("password")
.roles("USER")
.and()
.withUser("audit").password("audit")
.roles("USER", "ADMIN", "READER");
// @formatter:on
}
}
Run Code Online (Sandbox Code Playgroud)
OAuth2配置
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// @formatter:off
clients.inMemory()
.withClient("acme").secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token", "password")
.scopes("openid")
.and()
.withClient("trusted").secret("shuush")
.authorizedGrantTypes("client_credentials")
.scopes("openid");
// @formatter:on
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess("isAuthenticated()");
}
}
Run Code Online (Sandbox Code Playgroud)
更新1:
在配置中引入了自定义OAuth2RequestFactory,将checkUserScopes设置为true.虽然此设置适用于"client_credentails",但它无法获得"代码"授权.对于"代码"授权,DefaultOAuth2RequestFactory尝试在授权步骤期间映射客户端(acme)的权限而不是用户.其他想法是实现ClientDetailsService,它根据登录用户(admin/user)添加客户端(acme)的权限,但不确定如何从SecurityContext中获取登录用户,因为它在授权期间被客户端(acme)覆盖步.有任何想法吗?
public class ScopeMappingOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
private SecurityContextAccessor securityContextAccessor = new DefaultSecurityContextAccessor();
public ScopeMappingOAuth2RequestFactory(ClientDetailsService clientDetailsService) {
super(clientDetailsService);
super.setCheckUserScopes(true);
}
/**
* @param securityContextAccessor the security context accessor to set
*/
@Override
public void setSecurityContextAccessor(SecurityContextAccessor securityContextAccessor) {
this.securityContextAccessor = securityContextAccessor;
super.setSecurityContextAccessor(securityContextAccessor);
}
@Override
public AuthorizationRequest createAuthorizationRequest(Map<String, String> authorizationParameters) {
AuthorizationRequest request = super.createAuthorizationRequest(authorizationParameters);
if (securityContextAccessor.isUser()) {
request.setAuthorities(securityContextAccessor.getAuthorities());
}
return request;
}
}
Run Code Online (Sandbox Code Playgroud)
并更新相关代码
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
private InMemoryClientDetailsService clientDetailsService;
private Map<String, ClientDetails> clientDetailsStore;
public InMemoryClientDetailsService clientDetailsService() {
if (clientDetailsService == null) {
clientDetailsStore = new HashMap<String, ClientDetails>();
InMemoryClientDetailsService m = new InMemoryClientDetailsService() {
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
ClientDetails details = clientDetailsStore.get(clientId);
if (details == null) {
throw new NoSuchClientException("No client with requested id: " + clientId);
}
return details;
}
};
clientDetailsService = m;
}
return clientDetailsService;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
InMemoryClientDetailsServiceBuilder builder = new InMemoryClientDetailsServiceBuilder() {
@Override
protected void addClient(String clientId, ClientDetails value) {
clientDetailsStore.put(clientId, value);
}
@Override
protected ClientDetailsService performBuild() {
return clientDetailsService();
}
};
clients.setBuilder(builder);
// @formatter:off
builder
.withClient("acme").secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token", "password")
.scopes("openid", "apim.read", "apim.write")
.and()
.withClient("trusted").secret("shuush")
.authorizedGrantTypes("client_credentials")
.scopes("openid", "apim.read", "apim.write")
.authorities("openid", "apim.read", "apim.write");
// @formatter:on
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.requestFactory(new ScopeMappingOAuth2RequestFactory(clientDetailsService()));
}
Run Code Online (Sandbox Code Playgroud)
...}
LoginConfig
Configuration
@Order(-10)
protected static class LoginConfig extends WebSecurityConfigurerAdapter {
....
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.parentAuthenticationManager(authenticationManager);
// @formatter:off
auth.inMemoryAuthentication()
.withUser("admin").password("admin")
.roles("APIM.READ", "APIM.WRITE")
.and()
.withUser("user").password("password")
.roles("APIM.READ")
.and()
.withUser("audit").password("audit")
.roles("APIM.READ");
// @formatter:on
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,并且我还注意到代码运行了该checkUserScopes方法两次。我发现缺少的是用户和客户端都需要拥有您想要返回的权限。
因此,以这样的方式定义您的客户(根据您自己的角色调整角色):
@Bean
public ClientDetailsService clientDetailsService() {
Map<String, ClientDetails> clientDetailsStore = new HashMap<>();
Collection<String> scope = new HashSet<>();
scope.add("user");
scope.add("admin");
Collection<GrantedAuthority> authorities = new HashSet<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
Collection<String> authorizedGrantTypes = new HashSet<>();
authorizedGrantTypes.add("authorization_code");
BaseClientDetails clientDetails = new BaseClientDetails();
clientDetails.setClientId("clientid");
clientDetails.setClientSecret("{noop}secret"); //noop for Spring Security 5
clientDetails.setScope(scope);
clientDetails.setAuthorities(authorities);
clientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
clientDetailsStore.put("clientid", clientDetails);
InMemoryClientDetailsService clientDetailsService = new InMemoryClientDetailsService();
clientDetailsService.setClientDetailsStore(clientDetailsStore);
return clientDetailsService;
}
Run Code Online (Sandbox Code Playgroud)
现在客户端拥有所需的权限 user 和 admin。
并配置您的请求工厂:
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService());
defaultOAuth2RequestFactory.setCheckUserScopes(true);
endpoints.requestFactory(defaultOAuth2RequestFactory);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5763 次 |
| 最近记录: |