Información sobre la autenticación entre Java Applications y Oracle Identity Cloud Service

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 la descripción de lo siguiente:

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

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

  • Métodos y funciones del SDK de Java

Obtener Más Información sobre Flujos de Autenticación Tramitados

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

Para mayor seguridad, Oracle recomienda utilizar el flujo con tres leyendas 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.

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

La aplicación web Java implementa dos casos de uso: uno para autenticar usuarios y 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 #1: Autenticación de 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 código de solicitud para Oracle Identity Cloud Service y enviar esta URL como respuesta de redireccionamiento al explorador Web.

  3. El explorador web llama a la URL.

  4. Aparece la página de inicio de sesión de Oracle Identity Cloud Service.

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

  6. Una vez que el usuario se conecta, 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 backend (o de servidor a servidor) para intercambiar el código de autorización de 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 inicial .

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

Caso de uso #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 id contienen los detalles del usuario en el formato de un objeto JSON.

  4. La página Mi Perfil presenta el objeto JSON como contenido HTML.

Información sobre métodos y funciones

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

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

  • Minidev de Aplicación Externa de ASM 1.0.2

  • Apache Commons Collections 4.1

  • Apache Commons Lang 3.7

  • 2.3 de Analizador Rápido y Pequeño de JSON

  • LangTag 1.4.3 de Nimbus

  • Nimbus JOSE+JWT 5.14

  • SDK de OAuth 2.0 con OpenID Connect Extensions 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 tecnología de servlet para simplificar la experiencia de formación con el fin de comprender cómo funciona Java SDK. La aplicación utiliza Maven para obtener todas las bibliotecas y para generar un archivo de recurso de aplicación web (WAR).

Java SDK necesita una instancia de objeto HashMap cargada con la información de conexión de Oracle Identity Cloud Service. La aplicación web Java implementa 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 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 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 totalmente cualificada 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 de SDK.
Constants.LOG_LEVEL Indica el nivel de log del SDK.

La aplicación utiliza los atributos logoutSufix y redirectURL para evitar el código estricto de estos valores. El SDK no los necesita.

La aplicación web Java implementa la clase AuthServlet, que asigna la URL de /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 Java SDK 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);
    }
}

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

Nombre Descripción
redirectUrl Después de conectar un usuario, Oracle Identity Cloud Service redirecciona 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 redireccionamiento para la aplicación web Java.
scope Ámbito de autenticación de OAuth u OpenID Connect. Esta aplicación sólo necesita autenticación de openid.
state El protocolo OAuth define este parámetro. La aplicación web Java de ejemplo utiliza este código para comprobar si la comunicación se puede establecer con Oracle Identity Cloud Service. Para este ejemplo, el valor de este parámetro es 1234.
response_type Parámetro necesario para el tipo de permiso de código de autorización. Para este ejemplo, el valor de este parámetro es code.

Después de conectarse el usuario, Oracle Identity Cloud Service redirecciona el explorador web del usuario a una URL de devolución de llamada, que el desarrollador debe implantar. La aplicación web 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 identificador. A continuación, el servlet utiliza la instancia AuthenticationManager para validar el token de identificador. Los métodos AuthenticationManager.validateIdToken() devuelven una instancia del objeto IdToken que contiene información del usuario, como el nombre mostrado, el identificador de usuario y la lista de grupos y roles de aplicación asignados al usuario. Tanto el token de acceso como los valores del token de ID, 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 Java tiene otro URLs protegido: /private/myProfile.jsp.

La página myProfile.jsp utiliza el siguiente ejemplo de código para obtener más información sobre el usuario 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 del token de identificador 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 cerrar la sesión del usuario desde el inicio de sesión único entre la aplicación y Oracle Identity Cloud Service, la aplicación web Java implementa LogoutServlet, que asigna la URL de /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 de OAuth de Oracle Identity Cloud Service.