2015-11-19 19 views
9

Ho implementato la concessione di password OAuth2 con modulo di sicurezza a molla. Aggiungo la propria implementazione di UserDetails e UserDetailsService (jdbc). Inserisco l'utente nei miei controllori con:Spring Oauth2 - reload principal

dove Utente è la mia implementazione di UserDetails. Ora voglio aggiungere la possibilità di modificare i dati utente senza token di aggiornamento.

cerco di aggiornare presidi con:

User updatedUser = ... 
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(newAuth); 

Ma non funziona, quando invoco un altro metodo di controllo restituisce vecchio oggetto d'uso.

C'è un modo per modificare i dati utente senza token di aggiornamento? C'è qualche soluzione per fare in modo che la sicurezza di primavera carichi sempre i dati utente dal database (non dalla cache)?

+0

In quale livello della domanda non si aggiorna presidi? –

risposta

2

Ho trovato un modo per ottenere questo da this answer. Ho creato HttpSessionSecurityContextRepository

@Bean 
public ReloadUserPerRequestHttpSessionSecurityContextRepository userDetailContextRepository() { 
    return new ReloadUserPerRequestHttpSessionSecurityContextRepository(); 
} 

e aggiungi questo al mio HttpSecurity dalla classe di WebSecurityConfigurerAdapter come

.and() 
     .csrf() 
      .csrfTokenRepository(csrfTokenRepository()) 
    .and() 
     .securityContext() 
      .securityContextRepository(userDetailContextRepository()) 

Di seguito è riportato codici di esempio per recuperare informazioni utente aggiornata ad ogni richiesta. Puoi recuperare dal tuo server API o user-info-url della tua configurazione oauth2.

public class ReloadUserPerRequestHttpSessionSecurityContextRepository extends HttpSessionSecurityContextRepository { 

    @Override 
    public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) { 
     SecurityContext context = super.loadContext(requestResponseHolder); 

     Authentication auth = context.getAuthentication(); 
     if (auth != null && auth instanceof OAuth2Authentication) { 
      OAuth2Authentication oldAuth = (OAuth2Authentication) auth; 
      if (oldAuth.getPrincipal() instanceof LinkedHashMap) { 
       createNewUserDetailsFromPrincipal(oldAuth.getPrincipal()); 
      } 
      context.setAuthentication(oldAuth); 
     } 
     return context; 
    } 

    @SuppressWarnings("unchecked") 
    private void createNewUserDetailsFromPrincipal(Object principal) { 
     LinkedHashMap<String, Object> userDetailInfo = (LinkedHashMap<String, Object>) principal; 
     // fetch User informations from your API server or your database or 
     // 'user-info-url' of oauth2 endpoint 
     userDetailInfo.put("name", "EDITED_USER_NAME"); 
    } 

} 
1

non sono sicuro, ma questa è solo una supposizione, penso che è inoltre necessario cancellare SecurityContext.

contesto Prima chiara di sicurezza con SecurityContextHolder.clearContext(); quindi il codice per impostare l'autenticazione

Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(newAuth); 
+0

Le applicazioni protette da Oauth2 non possono essere assegnate con l'autenticazione di tipo "UsernamePasswordAuthenticationToken'. – Cataclysm

Problemi correlati