Saiba Mais sobre Autenticação entre Aplicativos Java e o Oracle Identity Cloud Service

Você está pronto para aprender sobre autenticação entre aplicativos Web Java e o Oracle Identity Cloud Service. Isso inclui compreender o seguinte:

  • O fluxo de autenticação de três etapas que o Oracle Identity Cloud Service suporta para o Java SDK

  • Casos de uso para usar um SDK com um aplicativo Java para autenticação com o Oracle Identity Cloud Service

  • Métodos e funções do Java SDK

Saiba Mais Sobre Fluxos de Autenticação de Três Etapas

O Oracle Identity Cloud Service suporta o fluxo de autenticação de três etapas para o SDK Java. Neste fluxo, os usuários interagem diretamente com o Oracle Identity Cloud Service. Depois que um usuário acessa, o Oracle Identity Cloud Service emite um código de autorização que o SDK troca por um token de acesso do usuário. O aplicativo Web Java usa esse token de acesso para conceder aos usuários acesso aos recursos protegidos no aplicativo. O fluxo de três etapas usa o tipo de concessão de código de autorização.

Para maior segurança, a Oracle recomenda que você use o fluxo de três etapas para integrar seus aplicativos Web Java com o Oracle Identity Cloud Service para autenticação. Usando o tipo de concessão de código de autorização, você também pode acessar outros aplicativos protegidos pelo Oracle Identity Cloud Service sem precisar se autenticar novamente.

Saiba Mais Sobre os Principais Casos de Uso para Usar um SDK com um Aplicativo Java

O aplicativo Java Web implementa dois casos de uso: um para autenticar usuários e o outro para acessar informações detalhadas sobre o usuário conectado.

Os diagramas de fluxo de dados a seguir ilustram o fluxo de eventos, chamadas e respostas entre o navegador da Web, o aplicativo da Web e o Oracle Identity Cloud Service para cada caso de uso.

Caso de Uso No 1: Autenticar um Usuário

O fluxo de dados acontece desta forma:

  1. O usuário solicita um recurso protegido.

  2. O módulo de autenticação usa o SDK para gerar um URL de código de autorização de solicitação para o Oracle Identity Cloud Service e enviar esse URL como resposta de redirecionamento para o Web browser.

  3. O navegador da Web chama o URL.

  4. A página Acessar do Oracle Identity Cloud Service é exibida.

  5. O usuário envia suas credenciais de acesso ao Oracle Identity Cloud Service.

  6. Depois que o usuário acessa, o Oracle Identity Cloud Service cria uma sessão para o usuário e emite um código de autorização.

  7. O aplicativo web faz uma chamada de back-end (ou servidor para servidor) para trocar o código de autorização por um token de acesso.

  8. O Oracle Identity Cloud Service emite um token de acesso e um token de id.

  9. Uma sessão é estabelecida e o usuário é redirecionado para a Home page.

  10. A Home page do aplicativo Web é exibida.

Caso de Uso No 2: Obter Detalhes Sobre o Usuário

O fluxo de dados acontece desta forma:

  1. O usuário solicita o recurso /myProfile.

  2. O aplicativo Web usa o SDK do Oracle Identity Cloud Service para validar o token de id.

  3. Os dados que retornam da validação do token de id contêm detalhes do usuário no formato de um objeto JSON.

  4. A página Meu Perfil renderiza o objeto JSON como conteúdo HTML.

Aprender sobre Métodos e Funções

O Java SDK é um arquivo JAR que você carrega como uma biblioteca de aplicativos Web. Este arquivo JAR requer essas bibliotecas de terceiros que você também deve carregar na biblioteca:

O arquivo zip do SDK Java contém as bibliotecas de terceiros necessárias a seguir para o SDK. Você pode carregá-los em seu aplicativo.

  • Ajuda do ASM Minidev 1.0.2

  • Coletas do Apache Commons 4.1

  • Idioma do Apache Commons 3.7

  • Parser JSON pequeno e rápido 2.3

  • Nimbus LangTag 1.4.3

  • Nimbus JOSE + JWT 5.14

  • OAuth 2.0 SDK com Extensões 5.30 do OpenID Connect

A Oracle fornece uma amostra de aplicativo Web Java para demonstrar como usar o SDK Java. Este aplicativo foi criado usando a tecnologia Servlet para simplificar a experiência de aprendizado e entender como o Java SDK funciona. O aplicativo usa o Maven para obter todas as bibliotecas e gerar um arquivo WAR (Web Application Resource).

O SDK Java requer uma instância do objeto HashMap carregada com informações de conexão do Oracle Identity Cloud Service. O aplicativo Web Java implementa essa instância HashMap como um atributo de classe na 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;
    }

Veja abaixo uma breve explicação de cada atributo necessário para este SDK:

Nome Descrição
IDCSTokenAssertionConfiguration.IDCS_HOST O sufixo de domínio da sua instância do Oracle Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_PORT O número da porta HTTPS reservado para sua instância do Oracle Identity Cloud Service (geralmente 443).
IDCSTokenAssertionConfiguration.IDCS_CLIENT_ID O valor do ID do Cliente gerado depois que você registra o aplicativo Web Java na console do Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_SECRET O valor do Segredo do Cliente gerado depois que você registra o aplicativo Web Java na console do Identity Cloud Service.
IDCSTokenAssertionConfiguration.IDCS_CLIENT_TENANT O prefixo de domínio da sua instância do Oracle Identity Cloud Service. Esse prefixo geralmente é um valor semelhante a idcs-abcd1234.
Constants.AUDIENCE_SERVICE_URL O URL de nome de domínio totalmente qualificado da sua instância do Oracle Identity Cloud Service.
Constants.TOKEN_ISSUER Para esse atributo, a Oracle recomenda que você mantenha o valor https://identity.oraclecloud.com.
Constants.TOKEN_CLAIM_SCOPE

O escopo controla os dados que o aplicativo pode acessar ou processar em nome do usuário do Oracle Identity Cloud Service.

Se o aplicativo usar o SDK para autenticar um usuário, o escopo será openid. Se o aplicativo também usar o SDK para obter detalhes sobre o usuário, o escopo será urn:opc:idm:t.user.me openid.

SSLEnabled Indica se o Oracle Identity Cloud Service responde a solicitações HTTPS ou HTTP. Para esse atributo, a Oracle recomenda que você mantenha o valor true.
Constants.CONSOLE_LOG Ativa o log do SDK.
Constants.LOG_LEVEL Indica o nível de log do SDK.

O aplicativo usa os atributos logoutSufix e redirectURL para evitar que esses valores sejam codificados. O SDK não os exige.

O aplicativo Web Java implementa a classe AuthServlet, que mapeia o URL /auth. Quando um usuário decide autenticar-se com o Oracle Identity Cloud Service, o Web browser faz uma solicitação a esse URL. A classe AuthServlet inicializa o objeto Authentication Manager, usa o SDK Java para gerar o URL do código de autorização do Oracle Identity Cloud Service e, em seguida, redireciona o Web browser para esse 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);
    }
}

Os seguintes parâmetros são usados para gerar o URL do código de autorização:

Nome Descrição
redirectUrl Depois que um usuário acessa, o Oracle Identity Cloud Service redireciona o Web browser do usuário para esse URL. Esse URL deve corresponder ao que você configurará para o aplicativo confiável na console do Identity Cloud Service. Consulte Registrar o Aplicativo Java para obter mais informações sobre como especificar um URL de redirecionamento para o aplicativo Web Java.
scope O escopo de autenticação OAuth ou OpenID Connect. Este aplicativo requer apenas autenticação openid.
state O protocolo OAuth define esse parâmetro. O aplicativo Web Java de amostra usa esse código para verificar se a comunicação pode ser estabelecida com o Oracle Identity Cloud Service. Para este exemplo, o valor desse parâmetro é 1234.
response_type O parâmetro exigido pelo tipo de concessão do código de autorização. Para este exemplo, o valor desse parâmetro é code.

Depois que o usuário acessa, o Oracle Identity Cloud Service redireciona o navegador Web do usuário para um URL de callback, que o desenvolvedor deve implementar. O aplicativo Web Java usa o CallbackServlet para tratar essa solicitação.

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

O aplicativo solicita o parâmetro de código de autorização e o usa para chamar o método AuthenticationManager.authorizationCode() do Java SDK para solicitar um token de acesso e um token de id. Em seguida, o servlet usa a instância AuthenticationManager para validar o token de id. Os métodos AuthenticationManager.validateIdToken() retornam uma instância do objeto IdToken que contém informações do usuário, como nome para exibição, id do usuário e a lista de grupos e atribuições de aplicativo designados ao usuário. Os valores do token de acesso e do token de id e algumas informações do usuário são armazenadas no objeto da sessão HTTP para que a solicitação possa ser encaminhada para um URL protegido dentro do aplicativo chamado /private/home.jsp. Além de /private/home.jsp, o aplicativo Web Java tem outros URLs protegidos: /private/myProfile.jsp.

A página myProfile.jsp usa a seguinte amostra de código para obter mais informações sobre o usuário que acessou o 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);
%>

A página /private/myProfile.jsp acessa o valor do token de id que foi definido na sessão, chama o método AuthenticationManager.validateIdToken() para recuperar informações do usuário e, em seguida, apresenta-o como conteúdo 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 o usuário do sign-on único entre o aplicativo e o Oracle Identity Cloud Service, o aplicativo Web Java implementa o LogoutServlet, que mapeia o 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);
    }
}

Esse servlet invalida a sessão do aplicativo e, em seguida, redireciona o Web browser do usuário para o URL de log-out OAuth do Oracle Identity Cloud Service.