java - example - Spring OAuth2 checkUserScopes no funciona como se esperaba
spring security rest token authentication (1)
En primer lugar, de acuerdo con Spring doc , si quiero asignar funciones de usuario a ámbitos, debo usar setCheckUserScopes (true) para DefaultOAuth2RequestFactory. Entonces, una forma de hacerlo es inyectar mi propio bean DefaultOAuth2RequestFactory, como dice el documento:
The AuthorizationServerEndpointsConfigurer allows you to inject a custom OAuth2RequestFactory so you can use that feature to set up a factory if you use @EnableAuthorizationServer.
Entonces lo hago
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends
AuthorizationServerConfigurerAdapter {
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.tokenServices(tokenServices());
endpoints
.getOAuth2RequestFactory(); // this doesn''t return me my own DefaultOAuth2RequestFactory
}
@Bean
@Primary
public OAuth2RequestFactory defaultOAuth2RequestFactory() {
DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(
clientDetailsService);
defaultOAuth2RequestFactory.setCheckUserScopes(true);
return defaultOAuth2RequestFactory;
}
}
EDITAR
He pasado por alto el método requestFactory () de AuthorizationServerEndpointsConfigurer. Esa era la forma correcta de pasarlo a Spring Security. Establecer el bean OAuth2RequestFactory como primario no funcionó. He eliminado algunas cosas para enfocarme en el problema real:
Después de esta observación, el problema real:
como yo entiendo, si el usuario tiene las autoridades A y B, y la aplicación tiene alcance A, entonces solo obtiene el alcance ''A''. Pero esto no está sucediendo. Lo que realmente está sucediendo es que si la aplicación tiene un alcance A, y la APLICACIÓN (no el usuario) tiene las autoridades A y B, entonces el usuario obtiene A. Pero esto no tiene ningún sentido. Este es el método DefaultOAuth2RequestFactory que resuelve los ámbitos del usuario:
private Set<String> extractScopes(Map<String, String> requestParameters, String clientId) {
... // I avoid some unimportant lines to not make this post so long
if ((scopes == null || scopes.isEmpty())) {
scopes = clientDetails.getScope();
}
if (checkUserScopes) {
scopes = checkUserScopes(scopes, clientDetails);
}
return scopes;
}
private Set<String> checkUserScopes(Set<String> scopes, ClientDetails clientDetails) {
if (!securityContextAccessor.isUser()) {
return scopes;
}
Set<String> result = new LinkedHashSet<String>();
Set<String> authorities = AuthorityUtils.authorityListToSet(securityContextAccessor.getAuthorities());
for (String scope : scopes) {
if (authorities.contains(scope) || authorities.contains(scope.toUpperCase())
|| authorities.contains("ROLE_" + scope.toUpperCase())) {
result.add(scope);
}
}
return result;
}
¿Es esto un error? Por favor dime si estoy equivocado. Saludos
Necesita cablear su OAuth2RequestFactory por código, algo así como aquí .
Si las autoridades están establecidas por ClientDetailsService, entonces deberías estar bien. Si buscas mapear las autoridades de usuario registradas no tengo suerte allí tampoco .