Avrei una domanda riguardante la configurazione di spring-security-oauth2 2.0.7. Sto facendo l'autenticazione tramite LDAP tramite un GlobalAuthenticationConfigurerAdapter:spring-security-oauth2 2.0.7 token di aggiornamento UserDetailsService Configuration - UserDetailsService è richiesto
@SpringBootApplication
@Controller
@SessionAttributes("authorizationRequest")
public class AuthorizationServer extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServer.class, args);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/oauth/confirm_access").setViewName("authorize");
}
@Configuration
public static class JwtConfiguration {
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
KeyPair keyPair = new KeyStoreKeyFactory(
new ClassPathResource("keystore.jks"), "foobar".toCharArray())
.getKeyPair("test");
converter.setKeyPair(keyPair);
return converter;
}
@Bean
public JwtTokenStore jwtTokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
}
@Configuration
@EnableAuthorizationServer
public static class OAuth2Config extends AuthorizationServerConfigurerAdapter implements EnvironmentAware {
private static final String ENV_OAUTH = "authentication.oauth.";
private static final String PROP_CLIENTID = "clientid";
private static final String PROP_SECRET = "secret";
private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds";
private RelaxedPropertyResolver propertyResolver;
@Inject
private AuthenticationManager authenticationManager;
@Inject
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Inject
private JwtTokenStore jwtTokenStore;
@Inject
private UserDetailsService userDetailsService;
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_OAUTH);
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(jwtTokenStore);
tokenServices.setAuthenticationManager(authenticationManager);
return tokenServices;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).tokenStore(jwtTokenStore).accessTokenConverter(
jwtAccessTokenConverter).userDetailsService(userDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess(
"isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(propertyResolver.getProperty(PROP_CLIENTID))
.scopes("read", "write")
.authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
.authorizedGrantTypes("authorization_code", "refresh_token", "password")
.secret(propertyResolver.getProperty(PROP_SECRET))
.accessTokenValiditySeconds(propertyResolver.getProperty(PROP_TOKEN_VALIDITY_SECONDS, Integer.class, 1800));
}
}
@Configuration
@Order(-10)
protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login").permitAll()
.and()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests().anyRequest().authenticated();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
@Configuration
protected static class AuthenticationConfiguration extends
GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource().ldif("classpath:test-server.ldif");
}
}
}
Mentre il token di aggiornamento funziona bene con il rilascio 2.0.6 della primavera-sicurezza-OAuth2, esso non funziona più con la versione 2.0.7. Come letto here, si dovrebbe impostare AuthenticationManager
da utilizzare quando si tenta di ottenere un nuovo token di accesso durante l'aggiornamento.
Per quanto ho capito, questo ha qualcosa a che fare con il cambio following di spring-security-oauth2.
Purtroppo non sono riuscito a configurarlo correttamente.
org.springframework.security.oauth2.provider.token.DefaultTokenServices#setAuthenticationManager
viene chiamato e ottiene un AuthenticationManager
iniettato. Non sono sicuro di aver capito come verrà iniettato lo LdapUserDetailsService
. L'unica cosa che vedo è che il PreAuthenticatedAuthenticationProvider
verrà chiamato durante il tentativo di autenticare nuovamente l'utente durante la chiamata di aggiornamento del token.
Qualcuno può consigliarmi su come farlo per favore?
ps: L'eccezione che sto ottenendo è la seguente:
p.PreAuthenticatedAuthenticationProvider : PreAuthenticated authentication request: org.springframework.security[email protected]5775: Principal: org.springframew[email protected]441d5545: Principal: bob; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: IllegalStateException, UserDetailsService is required.
Come descritto [qui] (https://github.com/spring-projects/spring-security-oauth/blob/e303652a911cf0168b5be68383ac120c23ec63b3/docs/oauth2 .md), 'userDetailsService: se si inietta un UserDetailsService o se uno è configurato globalmente in ogni caso (ad esempio in un GlobalAuthenticationManagerConfigurer), una concessione di token di aggiornamento conterrà un controllo sui dettagli dell'utente, per garantire che l'account sia ancora attivo. I mi sarei aspettato che il 'LdapUserDetailsService' venisse usato automaticamente. –
Così vorrei (e funziona per me). Puoi pubblicare un progetto completo? –
@ dave-syer, grazie mille per la risposta. Ho isolato il problema nel seguente progetto di test: https://github.com/jhoelter/zaas/tree/master/authserver c'è un tag chiamato ** spring-security-oauth2-2.0.6 ** dove funziona il token di aggiornamento bene. Quando si passa a 2.0.7 e si imposta la configurazione sopra descritta, si blocca. Molte grazie in anticipo per l'aiuto –