2016-03-12 28 views
5

Ho un'app Web Java che fornisce un servizio di ricerca e in alcuni casi deve controllare la sicurezza dei risultati. Se è importante, è implementato in Spring MVC e funziona sotto il molo.Autenticazione e rappresentazione di ADFS da un'applicazione Java (Spring MVC under Jetty)

Ho un cliente che vorrebbe l'autenticazione del web app per:

  • essere fatto tramite Active Directory Federation Services (ADFS) invece del meccanismo di build-in esistenti (per evitare un accesso separato).
  • Essere in grado di impersonare l'utente remoto sul server di ricerca, in modo che i controlli di sicurezza possano essere eseguiti eseguendo un'applicazione separata sul server di ricerca (che non conosce di per sé nulla su ADFS, ma è in grado di eseguire i controlli rilevanti quando eseguire come utente in questione).

E 'possibile, e se sì, come?

(Mi scuso se la terminologia mondo Windows è un po 'fuori - non è qualcosa che conosco molto circa, ma si spera che almeno l'intenzione è chiara)


Alcune note su pezzi del puzzle I' ve già guardato:

  1. Impersonating a user from a Java Servlet, è una domanda che ho avuto un certo numero di anni fa, che coprono più o meno lo stesso terreno, ma senza obbligo di ADFS - io non sono sicuro di come ADFS impatti cose, ma cialda (la soluzione per quella domanda) non sembra fornire alcun supporto per questo.
  2. Ho visto Java application with SSO (SAML) and ADFS e How do I talk to ADFS from Java?, che sembrano fornire un modo per l'autenticazione ADFS, ma non sono sicuro che sia compatibile con la rappresentazione successiva.
  3. Ho visto http://blogs.objectsharp.com/post/2010/09/10/Converting-Claims-to-Windows-Tokens-and-User-Impersonation.aspx e https://msdn.microsoft.com/en-au/library/ee517278.aspx, ma io sono sicuro:

    1. Se avrò l'accesso ai crediti necessari per fare questo se seguo il percorso SAML o OAuth sopra
    2. Che si tratti di possibile implementare che da dentro Java
  4. Penso che la seconda (rappresentazione) parte è più o meno lo stesso di Impersonating ASP.NET claims identity to windows identity, se non che io voglio farlo dal di dentro Java piuttosto che .Net.

risposta

3

Non si parla della versione di ADFS?

sono disponibili tre opzioni:

  • WS-Fed
  • SAML
  • OAuth2

nel mondo Java, SAML viene normalmente utilizzato. Che implica uno stack SAML.

Il collegamento SO sopra ha una risposta da me con collegamenti a un elenco di stack SAML.

Dal momento che si sta già utilizzando Spring, Spring Security sembra una buona soluzione.

Spring Security SAML Extension

ADFS attualmente non supporta OpenID Connect quali regole OAuth fuori.

Sì - Spring Security fornisce un elenco delle attestazioni generate da ADFS.

ADFS fornisce la rappresentazione tramite Identity Delegation.

Sfortunatamente, questo viene fatto normalmente tramite WCF e WIF (entrambi i costrutti .NET).

3

Ho un'applicazione simile: il mio è un client Swing piuttosto che un'applicazione web, ma il processo dovrebbe essere simile. È necessario inviare query con un ruolo assunto utilizzando un'API AWS dopo aver effettuato l'autenticazione con un server ADFS locale. Nel nostro ambiente, ADFS è stato configurato per fornire asserzioni SAML e AWS è stato configurato per riconoscerle. Quindi, questo è quello che faccio:

  1. Quando richiesto, l'applicazione richiede all'utente per le loro solite credenziali di rete e questi sono utilizzati per richiedere un SAML da ADFS. Io uso Apache HttpClient per effettuare la chiamata:

    private String getAdfsResponse(String username, String password) throws Exception { 
    
    log.debug("Trying to log onto ADFS server for {}", username); 
    
    // Lax redirect policy is needed so that all HTTP 302 redirects are followed after hitting the initial ADFS URL. 
    try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { 
    
        HttpUriRequest login = RequestBuilder.post() 
          .setUri(new URI(ADFS_URL)) 
          .addParameter("UserName", username) 
          .addParameter("Password", password) 
          .build(); 
    
        CloseableHttpResponse response = httpClient.execute(login); 
    
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
    
         HttpEntity responseEntity = response.getEntity(); 
         String adfsResponse = EntityUtils.toString(responseEntity, "UTF-8"); 
         log.debug("ADFS server responded with {}", adfsResponse); 
         return adfsResponse; 
    
        } else { 
    
         throw new Exception("ADFS server responded with " + response.getStatusLine()); 
    
        } 
    } 
    } 
    
  2. Se le credenziali vengono convalidate, ADFS restituisce una risposta SAML che assomiglia a un modulo HTML, ma contiene un elemento input con un paio SAMLResponse nome/valore.

  3. Quando l'attributo SAMLResponsevalue è base64 decodificato conterrà l'asserzione SAML. Per AWS, ho bisogno di estrarre alcune informazioni sul ruolo e io uso questo, insieme all'intero SAMLResponse, per chiamare AWS STS (servizio token di sicurezza). Se tutto va bene con AWS, ricevo un set di credenziali di sicurezza provvisorie che posso utilizzare per le query che desidero veramente fare. L'intero viaggio di andata è descritto in http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html

Tutto questo dipende ADFS e l'altra parte essendo SAML-configurati, e per l'altra parte a fornire un'API adeguato che consente di assumere un ruolo particolare dalla loro parte. È questo il genere di cose che stai affrontando?

+0

Penso che il nocciolo del mio problema è che l'altra parte non supporta questo, quindi il modo in cui abbiamo interagito con esso è impersonando l'utente remoto con CreateProcessAsUser (https://msdn.microsoft.com /en-au/library/windows/desktop/ms682429(v=vs.85).aspx) tramite JNI, ma nel mondo ADFS/SAML, non è chiaro come ottenere il token di cui ha bisogno la funzione. –