Más información sobre la autenticación entre aplicaciones Java y Oracle Identity Cloud Service

Ya está listo para obtener más información sobre la autenticación entre las aplicaciones web de Java y Oracle Identity Cloud Service. Esto incluye comprender lo siguiente:

  • Flujo de autenticación de tres partes que soporta Oracle Identity Cloud Service para el SDK de Java

  • Casos de uso de un SDK con una aplicación Java para autenticarse con Oracle Identity Cloud Service

  • Métodos y funciones del SDK de Java

Más información sobre flujos de autenticación de tres segmentos

Oracle Identity Cloud Service soporta el flujo de autenticación de tres partes para el SDK de Java. En este flujo, los usuarios interactúan directamente con Oracle Identity Cloud Service. Después de que un usuario se conecte, Oracle Identity Cloud Service emite un código de autorización que el SDK intercambia para un token de acceso de usuario. La aplicación web de Java utiliza este token de acceso para otorgar a los usuarios acceso a los recursos protegidos de la aplicación. El flujo de tres partes utiliza el tipo de permiso de código de autorización.

Para aumentar la seguridad, Oracle recomienda utilizar el flujo de tres partes para integrar las aplicaciones web de Java con Oracle Identity Cloud Service para la autenticación. Mediante el tipo de permiso de código de autorización, también puede acceder a otras aplicaciones protegidas por Oracle Identity Cloud Service sin tener que volver a autenticarse.

Información sobre los casos de uso principales para el uso de un SDK con una aplicación Java

La aplicación web de Java implementa dos casos de uso: uno para autenticar usuarios y el otro para acceder a información detallada sobre el usuario conectado.

Los siguientes diagramas de flujo de datos ilustran el flujo de eventos, llamadas y respuestas entre el explorador web, la aplicación web y Oracle Identity Cloud Service para cada caso de uso.

Caso de uso n.o 1: Autenticar un usuario

El flujo de datos se produce de esta forma:

  1. El usuario solicita un recurso protegido.

  2. El módulo de autenticación utiliza el SDK para generar una URL de solicitud-autorización-código para Oracle Identity Cloud Service y enviar esta URL como respuesta de redirección al explorador web.

  3. El explorador web llama a la URL.

  4. Aparecerá la página Conectar de Oracle Identity Cloud Service.

  5. El usuario envía sus credenciales de conexión de Oracle Identity Cloud Service.

  6. Después de que el usuario se conecte, Oracle Identity Cloud Service crea una sesión para el usuario y emite un código de autorización.

  7. La aplicación web realiza una llamada de backend (o de servidor a servidor) para intercambiar el código de autorización por un token de acceso.

  8. Oracle Identity Cloud Service emite un token de acceso y un token de ID.

  9. Se establece una sesión y se redirige al usuario a la página Inicio.

  10. Aparece la página Inicio de la aplicación web.

Caso de uso n.o 2: Obtener detalles sobre el usuario

El flujo de datos se produce de esta forma:

  1. El usuario solicita el recurso /myProfile.

  2. La aplicación web utiliza el SDK de Oracle Identity Cloud Service para validar el token de ID.

  3. Los datos que se devuelven de la validación del token de ID contienen los detalles del usuario con el formato de un objeto JSON.

  4. La página Mi perfil representa el objeto JSON como contenido HTML.

Más información sobre métodos y funciones

El SDK de Java es un archivo JAR que se carga como biblioteca de aplicaciones web. Este archivo JAR requiere estas bibliotecas de terceros que también debe cargar en la biblioteca:

El archivo zip de Java SDK contiene las siguientes bibliotecas de terceros necesarias para el SDK. Puede cargarlos en la aplicación.

  • Ayudante de ASM Minidev 1.0.2

  • Recopilaciones de Apache Commons 4.1

  • Lenguaje de Apache Commons 3.7

  • Analizador JSON pequeño y rápido 2.3

  • Nimbus LangTag 1.4.3

  • Nimbus JOSE+JWT 5.14

  • SDK de OAuth 2.0 con extensiones de Connect OpenID 5.30

Oracle proporciona una aplicación web Java de ejemplo para demostrar cómo utilizar el SDK de Java. Esta aplicación se ha creado con la tecnología Servlet para simplificar la experiencia de aprendizaje y comprender cómo funciona el SDK de Java. La aplicación utiliza Maven para obtener todas las bibliotecas y generar un archivo de recurso de aplicación web (WAR).

El SDK de Java necesita una instancia de objeto HashMap cargada con información de conexión de Oracle Identity Cloud Service. La aplicación web Java implanta esta instancia HashMap como atributo de clase en la clase 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;
    }

A continuación se muestra una breve explicación de cada atributo necesario para este SDK:

Nombre Descripción
IDCSTokenAssertionConfiguration.IDCS_HOST Sufijo de dominio de la instancia de Oracle Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_PORT Número de puerto HTTPS reservado para la instancia de Oracle Identity Cloud Service (normalmente 443).
IDCSTokenAssertionConfiguration.IDCS_CLIENT_ID Valor del ID de cliente que se genera después de registrar la aplicación web de Java en la consola de Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_SECRET Valor del secreto de cliente que se genera después de registrar la aplicación web de Java en la consola de Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_TENANT Prefijo de dominio de la instancia de Oracle Identity Cloud Service. Este prefijo suele ser un valor similar a idcs-abcd1234.
Constants.AUDIENCE_SERVICE_URL URL de nombre de dominio completo de la instancia de Oracle Identity Cloud Service.
Constants.TOKEN_ISSUER Para este atributo, Oracle recomienda mantener el valor https://identity.oraclecloud.com.
Constants.TOKEN_CLAIM_SCOPE

El ámbito controla los datos a los que la aplicación puede acceder o procesar en nombre del usuario de Oracle Identity Cloud Service.

Si la aplicación utiliza el SDK para autenticar un usuario, el ámbito es openid. Si la aplicación también utiliza el SDK para obtener detalles sobre el usuario, el ámbito es urn:opc:idm:t.user.me openid.

SSLEnabled Indica si Oracle Identity Cloud Service responde a solicitudes HTTPS o HTTP. Para este atributo, Oracle recomienda mantener el valor true.
Constants.CONSOLE_LOG Activa el log del SDK.
Constants.LOG_LEVEL Indica el nivel de log del SDK.

La aplicación utiliza los atributos logoutSufix y redirectURL para evitar codificar estos valores. El SDK no los necesita.

La aplicación web Java implanta la clase AuthServlet, que asigna la URL /auth. Cuando un usuario decide autenticarse con Oracle Identity Cloud Service, el explorador web realiza una solicitud a esta URL. La clase AuthServlet inicializa el objeto Authentication Manager, utiliza el SDK de Java para generar la URL de código de autorización de Oracle Identity Cloud Service y, a continuación, redirige el explorador web a esta 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);
    }
}

Se utilizan los siguientes parámetros para generar la URL del código de autorización:

Nombre Descripción
redirectUrl Después de que un usuario se conecte, Oracle Identity Cloud Service redirige el explorador web del usuario a esta URL. Esta URL debe coincidir con la que configurará para la aplicación de confianza en la consola de Identity Cloud Service. Consulte Registrar la aplicación Java para obtener más información sobre la especificación de una URL de redirección para la aplicación web Java.
scope Ámbito de autenticación de OAuth o OpenID Connect. Esta aplicación solo necesita autenticación openid.
state El protocolo OAuth define este parámetro. La aplicación web de Java de ejemplo utiliza este código para comprobar si se puede establecer la comunicación con Oracle Identity Cloud Service. Para este ejemplo, el valor de este parámetro es 1234.
response_type Parámetro requerido por el tipo de permiso de código de autorización. Para este ejemplo, el valor de este parámetro es code.

Después de que el usuario se conecte, Oracle Identity Cloud Service redirige el explorador web del usuario a una URL de devolución de llamada, que el desarrollador debe implantar. La aplicación web de Java utiliza CallbackServlet para manejar esta solicitud.

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);
    }
}	

La aplicación solicita el parámetro de código de autorización y lo utiliza para llamar al método AuthenticationManager.authorizationCode() del SDK de Java para solicitar un token de acceso y un token de ID. A continuación, el servlet utiliza la instancia AuthenticationManager para validar el token de ID. Los métodos AuthenticationManager.validateIdToken() devuelven una instancia del objeto IdToken que contiene información del usuario, como el nombre mostrado, el ID de usuario y la lista de grupos y roles de aplicación asignados al usuario. Los valores de token de acceso y token de ID, así como parte de la información de usuario, se almacenan en el objeto de sesión HTTP para que la solicitud se pueda reenviar a una URL protegida dentro de la aplicación denominada /private/home.jsp. Además de /private/home.jsp, la aplicación web de Java tiene otras URL protegidas: /private/myProfile.jsp.

La página myProfile.jsp utiliza el siguiente ejemplo de código para obtener más información sobre el usuario que se ha conectado 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 página /private/myProfile.jsp accede al valor de token de ID definido en la sesión, llama al método AuthenticationManager.validateIdToken() para recuperar la información del usuario y, a continuación, la presenta como contenido 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>

Para desconectar al usuario de la conexión única entre la aplicación y Oracle Identity Cloud Service, la aplicación web de Java implanta LogoutServlet, que asigna la 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);
    }
}

Este servlet invalida la sesión de la aplicación y, a continuación, redirige el explorador web del usuario a la URL de desconexión OAuth de Oracle Identity Cloud Service.