Informazioni sull'autenticazione tra applicazioni Java e Oracle Identity Cloud Service

Si è pronti per informazioni sull'autenticazione tra le applicazioni Web Java e Oracle Identity Cloud Service. Ciò include quanto riportato di seguito.

  • Il flusso di autenticazione a tre fasi supportato da Oracle Identity Cloud Service per Java SDK

  • Casi d'uso di un SDK con un'applicazione Java per eseguire l'autenticazione con Oracle Identity Cloud Service

  • Metodi e funzioni dell'SDK di Java

Informazioni sui flussi di autenticazione tridimensionali

Oracle Identity Cloud Service supporta il flusso di autenticazione a tre fasi per l'SDK Java. In questo flusso gli utenti interagiscono direttamente con Oracle Identity Cloud Service. Dopo che un utente si collega, Oracle Identity Cloud Service emette un codice di autorizzazione che viene scambiato da un token di accesso utente. L'applicazione Web Java utilizza questo token di accesso per concedere agli utenti l'accesso alle risorse protette nell'applicazione. Il flusso a tre fasi utilizza il tipo di autorizzazione codice autorizzazione.

Per una maggiore sicurezza, Oracle consiglia di utilizzare il flusso a tre fasi per integrare le applicazioni Web Java con Oracle Identity Cloud Service per l'autenticazione. Utilizzando il tipo di concessione del codice autorizzazione, è inoltre possibile accedere ad altre applicazioni protette da Oracle Identity Cloud Service senza dover ripetere l'autenticazione.

Informazioni sui casi d'uso principali per l'uso di un SDK con un'applicazione Java

L'applicazione Web Java implementa due casi d'uso: uno per l'autenticazione degli utenti e l'altro per accedere alle informazioni dettagliate sull'utente collegato.

I diagrammi di flusso di dati seguenti illustrano il flusso di eventi, chiamate e risposte tra il browser Web, l'applicazione Web e Oracle Identity Cloud Service per ogni caso d'uso.

Caso d'uso n. 1: autenticazione di un utente

Il flusso di dati viene eseguito in questo modo:

  1. L'utente richiede una risorsa protetta.

  2. Il modulo di autenticazione utilizza l'SDK per generare l'URL del codice di richiesta per Oracle Identity Cloud Service e inviare questo URL come risposta di reindirizzamento al browser Web.

  3. Il browser Web chiama l'URL.

  4. Viene visualizzata la pagina Collegamento di Oracle Identity Cloud Service.

  5. L'utente sottomette le credenziali di accesso a Oracle Identity Cloud Service.

  6. Dopo che l'utente si collega, Oracle Identity Cloud Service crea una sessione per l'utente ed emette un codice di autorizzazione.

  7. L'applicazione Web effettua una chiamata backend (o da server a server) per scambiare il codice di autorizzazione per un token di accesso.

  8. Oracle Identity Cloud Service emette un token di accesso e un token di ID.

  9. Viene stabilita una sessione e l'utente viene reindirizzato alla home page .

  10. Viene visualizzata la home page dell'applicazione Web.

Caso d'uso n. 2: informazioni dettagliate sull'utente

Il flusso di dati viene eseguito in questo modo:

  1. L'utente richiede la risorsa /myProfile.

  2. L'applicazione Web utilizza l'SDK di Oracle Identity Cloud Service per convalidare il token ID.

  3. I dati restituiti dalla convalida del token ID contengono i dettagli dell'utente nel formato di un oggetto JSON.

  4. La pagina Profilo personale presenta l'oggetto JSON come contenuto HTML.

Informazioni sui metodi e sulle funzioni

SDK di Java è un file JAR che viene caricato come libreria delle applicazioni Web. Questo file JAR richiede le seguenti librerie di terze parti che è necessario caricare nella libreria:

Il file ZIP SDK Java contiene le librerie di terze parti necessarie per l'SDK. È possibile caricarli nell'applicazione.

  • Minidev 1.0.2 applicazione di supporto ASM

  • Apache Commons Collections 4.1

  • Apache Commons Lang 3.7

  • Parser semplice e rapido JSON 2.3

  • Nimbus LangTag 1.4.3

  • Nimbus JOSE+JWT 5.14

  • OAuth 2.0 SDK con OpenID Connect Extensions 5.30

Oracle fornisce un'applicazione Web Java di esempio per dimostrare come utilizzare l'SDK Java. Questa applicazione è stata creata utilizzando la tecnologia servlet per semplificare l'esperienza di apprendimento per comprendere come funziona Java SDK. L'applicazione utilizza Maven per ottenere tutte le librerie e generare un file WAR (Web Application Resource).

L'SDK di Java richiede il caricamento di un'istanza dell'oggetto HashMap con le informazioni di connessione di Oracle Identity Cloud Service. L'applicazione Web Java implementa questa istanza HashMap come attributo di classe nella classe ConnectionOptions.java.

//Instance of a HashMap.
    private Map<String,Object> options = new HashMap<>();
  
public ConnectionOptions(){
        this.options = new HashMap<>();
}
  
public Map<String,Object> getOptions(){
        //Adding Oracle Identity Cloud Service connection parameters to the HashMap instance.
        this.options.put(IDCSTokenAssertionConfiguration.IDCS_HOST, "identity.oraclecloud.com");
        this.options.put(IDCSTokenAssertionConfiguration.IDCS_PORT, "443");
        this.options.put(IDCSTokenAssertionConfiguration.IDCS_CLIENT_ID, "123456789abcdefghij");
        this.options.put(IDCSTokenAssertionConfiguration.IDCS_CLIENT_SECRET, "abcde-12345-zyxvu-98765-qwerty");
        this.options.put(IDCSTokenAssertionConfiguration.IDCS_CLIENT_TENANT, "idcs-abcd1234");
        this.options.put(Constants.AUDIENCE_SERVICE_URL, "https://idcs-abcd1234.identity.oraclecloud.com");
        this.options.put(Constants.TOKEN_ISSUER, "https://identity.oraclecloud.com/");
        this.options.put(Constants.TOKEN_CLAIM_SCOPE, "urn:opc:idm:t.user.me openid");
        this.options.put("SSLEnabled", "true");
        this.options.put("redirectURL", "http://localhost:8080/callback");
        this.options.put("logoutSufix", "/oauth2/v1/userlogout");
        this.options.put(Constants.CONSOLE_LOG, "True");
        this.options.put(Constants.LOG_LEVEL, "DEBUG");
        return this.options;
    }

Di seguito è riportata una breve spiegazione di ogni attributo richiesto per questo SDK:

Nome Descrizione
IDCSTokenAssertionConfiguration.IDCS_HOST Suffisso di dominio dell'istanza di Oracle Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_PORT Il numero della porta HTTPS riservata per l'istanza di Oracle Identity Cloud Service (in genere 443).
IDCSTokenAssertionConfiguration.IDCS_CLIENT_ID Il valore dell'ID client generato dopo la registrazione dell'applicazione Web Java nella console di Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_SECRET Il valore del segreto client generato dopo la registrazione dell'applicazione Web Java nella console di Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_TENANT Prefisso di dominio dell'istanza Oracle Identity Cloud Service. Questo prefisso in genere è un valore simile a idcs-abcd1234.
Constants.AUDIENCE_SERVICE_URL L'URL del nome dominio completamente qualificato dell'istanza di Oracle Identity Cloud Service.
Constants.TOKEN_ISSUER Per questo attributo, Oracle consiglia di conservare il valore https://identity.oraclecloud.com.
Constants.TOKEN_CLAIM_SCOPE

L'ambito controlla i dati che l'applicazione può accedere o elaborare per conto dell'utente Oracle Identity Cloud Service.

Se l'applicazione utilizza il kit SDK per autenticare un utente, l'ambito è openid. Se l'applicazione utilizza anche l'SDK per ottenere i dettagli dell'utente, l'ambito è urn:opc:idm:t.user.me openid.

SSLEnabled Indica se Oracle Identity Cloud Service risponde alle richieste HTTPS o HTTP. Per questo attributo, Oracle consiglia di conservare il valore true.
Constants.CONSOLE_LOG Abilita il log SDK.
Constants.LOG_LEVEL Indica il livello di log dell'SDK.

L'applicazione utilizza entrambi gli attributi logoutSufix e redirectURL per evitare il codice assoluto di questi valori. L'SDK non li richiede.

L'applicazione Web Java implementa la classe AuthServlet, che mappa l'URL di /auth. Quando un utente decide di eseguire l'autenticazione con Oracle Identity Cloud Service, il browser Web effettua una richiesta per l'URL. La classe AuthServlet inizializza l'oggetto Authentication Manager, utilizza Java SDK per generare l'URL del codice di autorizzazione di Oracle Identity Cloud Service e reindirizza il browser Web a questo URL.

public class AuthServlet extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Loading the configurations
        Map<String, Object> options = new ConnectionOptions().getOptions();
        //Configuration object instance with the parameters loaded.
        IDCSTokenAssertionConfiguration config = new IDCSTokenAssertionConfiguration(options);
	String redirectUrl = (String)options.get("redirectURL");
        String scope = (String)options.get(Constants.TOKEN_CLAIM_SCOPE);
        //Authentication Manager loaded with the configurations.
        AuthenticationManager am = AuthenticationManagerFactory.getInstance(config);
        //Using Authentication Manager to generate the Authorization Code URL, passing the
        //application's callback URL as parameter, along with code value and code parameter.
        String authzURL = am.getAuthorizationCodeUrl(redirectUrl, scope, "1234", "code");
        //Redirecting the browser to the Oracle Identity Cloud Service Authorization URL.
        response.sendRedirect(authzURL);
    }
}

I seguenti parametri vengono utilizzati per generare l'URL del codice di autorizzazione:

Nome Descrizione
redirectUrl Dopo che un utente si collega, Oracle Identity Cloud Service reindirizza il browser Web dell'utente a questo URL. Questo URL deve corrispondere a quello che verrà configurato per l'applicazione protetta nella console di Identity Cloud Service. Per ulteriori informazioni su come specificare un URL di reindirizzamento per l'applicazione Web Java, vedere Registrare l'applicazione Java.
scope L'ambito di autenticazione OAuth o OpenID Connect. Questa applicazione richiede solo l'autenticazione openid.
state Il protocollo OAuth definisce questo parametro. L'applicazione Web Java di esempio utilizza questo codice per controllare se è possibile stabilire la comunicazione con Oracle Identity Cloud Service. Per questo esempio, il valore di questo parametro è 1234.
response_type Il parametro richiesto dal tipo di autorizzazione del codice di autorizzazione. Per questo esempio, il valore di questo parametro è code.

Dopo che l'utente si collega, Oracle Identity Cloud Service reindirizza il browser Web dell'utente a un URL di callback che deve implementare lo sviluppatore. L'applicazione Web Java utilizza CallbackServlet per gestire questa richiesta.

public class CallbackServlet extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Loading the configurations
        Map<String, Object> options = new ConnectionOptions().getOptions();
        //After Oracle Identity Cloud Service authenticates the user, the browser is redirected to the
        //callback URL, implemented as a Servlet.
        IDCSTokenAssertionConfiguration config = new IDCSTokenAssertionConfiguration(options);
        //Authentication Manager loaded with the configurations.
        AuthenticationManager am = AuthenticationManagerFactory.getInstance(config);
        //Getting the authorization code from the "code" parameter
        String authzCode = request.getParameter("code");
        //Using the Authentication Manager to exchange the Authorization Code to an Access Token.
        AuthenticationResult ar = am.authorizationCode(authzCode);
        //Getting the Access Token object and its String value.
        AccessToken access_token = ar.getToken(OAuthToken.TokenType.ACCESS_TOKEN);
        String access_token_string = access_token.getToken();
        //Getting the ID Token object and its String value.
        IdToken id_token = ar.getToken(OAuthToken.TokenType.ID_TOKEN);
        String id_token_string = id_token.getToken();
        //Validating both Tokens to acquire information for User such as UserID, 
        //DisplayName, list of groups and AppRoles assigned to the user.
        IdToken id_token_validated = am.validateIdToken(id_token_string);
        //Storing information into the HTTP Session.
        HttpSession session=request.getSession();
        session.setAttribute("access_token", access_token_string);
        session.setAttribute("id_token", id_token_string);
        session.setAttribute("userId", id_token_validated.getUserId());
        session.setAttribute("displayName", id_token_validated.getDisplayName());
	//Forwarding the request to the Home page.
        request.getRequestDispatcher("private/home.jsp").forward(request, response);
    }
}	

L'applicazione richiede il parametro del codice di autorizzazione e lo utilizza per richiamare il metodo AuthenticationManager.authorizationCode() dell'SDK Java per richiedere sia un token di accesso che un token ID. Il servlet utilizza quindi l'istanza AuthenticationManager per convalidare il token ID. I metodi AuthenticationManager.validateIdToken() restituiscono un'istanza dell'oggetto IdToken contenente informazioni utente quali il nome visualizzato, l'ID utente e l'elenco dei gruppi e dei ruoli applicazione assegnati all'utente. I valori dei token di accesso e ID e alcune informazioni utente vengono memorizzati nell'oggetto sessione HTTP in modo che la richiesta possa essere inoltrata a un URL protetto all'interno dell'applicazione denominata /private/home.jsp. Oltre a /private/home.jsp, l'applicazione Web Java dispone di un altro URLs protetto: /private/myProfile.jsp.

La pagina myProfile.jsp utilizza l'esempio di codice riportato di seguito per ottenere ulteriori informazioni sull'utente collegato a Oracle Identity Cloud Service.


<%if(session.getAttribute("access_token")==null) response.sendRedirect("/login.html");%>
<!DOCTYPE html>
<%
/**
 * The /private/myProfile.jsp page accesses the user's access token previously set in the session, 
 * calls the getAuthenticatedUser method to retrieve the user's information, and then formats it as HTML.
 * @author felippe.oliveira@oracle.com
 * @Copyright Oracle
*/
  java.util.Map<String, Object> options = new sampleapp.util.ConnectionOptions().getOptions();
  //Configuration object instance with the parameters loaded.
  oracle.security.jps.idcsbinding.shared.IDCSTokenAssertionConfiguration configuration = new oracle.security.jps.idcsbinding.shared.IDCSTokenAssertionConfiguration(options);
  oracle.security.jps.idcsbinding.shared.AuthenticationManager am = oracle.security.jps.idcsbinding.shared.AuthenticationManagerFactory.getInstance(configuration);
  
  //Getting the Access Token and the Id Token from the session object
  String access_token_string = (String)session.getAttribute("access_token");
  String id_token_string = (String)session.getAttribute("id_token");

  //Validating the ID Token to get user information, groups and app roles associated with the user.
  oracle.security.jps.idcsbinding.api.AccessToken access_token_validated = am.validateAccessToken(access_token_string);
  oracle.security.jps.idcsbinding.api.IdToken id_token_validated = am.validateIdToken(id_token_string);
%>

La pagina /private/myProfile.jsp accede al valore del token ID impostato nella sessione, richiama il metodo AuthenticationManager.validateIdToken() per recuperare le informazioni dell'utente e le presenta sotto forma di contenuto HTML.


<p><b>Information from the Identity Token:</b></p><p><%
out.println("DisplayName = "+ id_token_validated.getDisplayName() +"<br>");
out.println("IdentityDomain = "+ id_token_validated.getIdentityDomain() +"<br>");
out.println("UserName = "+ id_token_validated.getUserName()+"<br>");
out.println("UserId = "+ id_token_validated.getUserId()+"<br>");
out.println("Issuer = "+ id_token_validated.getIssuer()+"<br>");

java.util.List<oracle.security.jps.idcsbinding.api.IDCSAppRole> appRoles = id_token_validated.getAppRoles();
if(!appRoles.isEmpty()){
   out.println("App Roles:<br>");
   for(oracle.security.jps.idcsbinding.api.IDCSAppRole appRole: appRoles){
      out.println("&nbsp;appRole = "+ appRole.getName() +"<br>");
   }//for
}//if

java.util.List<oracle.security.jps.idcsbinding.api.IDCSGroup> groups = id_token_validated.getGroupMembership();
if(!groups.isEmpty()){
   out.println("Groups:<br>");
   for(oracle.security.jps.idcsbinding.api.IDCSGroup group: groups){
      out.println("&nbsp;group = "+ group.getName() +"<br>");
   }//for
}//if
%>
</p>
<p><b>Access Token:</b></p><p><%=access_token_string%></p>

Per firmare l'utente da Single Sign-On tra l'applicazione e Oracle Identity Cloud Service, l'applicazione Web Java implementa LogoutServlet, che mappa l'URL /logout:

public class LogoutServlet extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session=request.getSession();
        String id_token = (String)session.getAttribute("id_token");
        session.invalidate();
        Map options = new ConnectionOptions().getOptions();
        String logoutURL = (String)options.get(Constants.AUDIENCE_SERVICE_URL) + (String)options.get("logoutSufix") +"?post_logout_redirect_uri=http%3A//localhost%3A8080&id_token_hint="+ id_token;
        response.sendRedirect(logoutURL);
    }
}

Questo servlet invalida la sessione dell'applicazione e reindirizza il browser Web dell'utente all'URL di logout OAuth di Oracle Identity Cloud Service.