gpt4 book ai didi

spring-security - 将用户角色映射到oauth2范围/权限

转载 作者:行者123 更新时间:2023-12-03 20:59:36 25 4
gpt4 key购买 nike

我们有一个权利数据库,其中包含应用程序ID,角色和每个应用程序映射到角色的用户。遵循advice on thread如何根据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
}
}


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()");
}
}


更新1:

在配置中引入了自定义 OAuth2RequestFactory以将checkUserScopes设置为true。虽然此设置适用于“ client_credentails”,但不适用于“代码”授予。对于“代码”授予, DefaultOAuth2RequestFactory在授权步骤中尝试为客户端(acme)而不是用户为 maps authorities
另一个想法是实施 ClientDetailsService,该操作基于登录的用户(管理员/用户)添加客户端(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;
}

}


并将相关代码更新为

@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()));
}


...
}

登录配置

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
}
}

最佳答案

我遇到了同样的问题,并且我还注意到代码两次运行了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;
}


现在,客户端具有所需的权限用户和管理员。

并配置您的请求工厂:

    @Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {

DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService());
defaultOAuth2RequestFactory.setCheckUserScopes(true);
endpoints.requestFactory(defaultOAuth2RequestFactory);
}

关于spring-security - 将用户角色映射到oauth2范围/权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31345466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com