/**
   * Process the authorization request and issue an authorization code or access token depending on
   * the Response Type available in the request.
   *
   * @param oAuth2AuthorizeReqDTO <code>OAuth2AuthorizeReqDTO</code> containing information about
   *     the authorization request.
   * @return <code>OAuth2AuthorizeRespDTO</code> instance containing the access token/authorization
   *     code or an error code.
   */
  public OAuth2AuthorizeRespDTO authorize(OAuth2AuthorizeReqDTO oAuth2AuthorizeReqDTO) {

    if (log.isDebugEnabled()) {
      log.debug(
          "Authorization Request received for user : "******", Client ID : "
              + oAuth2AuthorizeReqDTO.getConsumerKey()
              + ", Authorization Response Type : "
              + oAuth2AuthorizeReqDTO.getResponseType()
              + ", Requested callback URI : "
              + oAuth2AuthorizeReqDTO.getCallbackUrl()
              + ", Requested Scope : "
              + OAuth2Util.buildScopeString(oAuth2AuthorizeReqDTO.getScopes()));
    }

    try {
      AuthorizationHandlerManager authzHandlerManager = AuthorizationHandlerManager.getInstance();
      return authzHandlerManager.handleAuthorization(oAuth2AuthorizeReqDTO);
    } catch (Exception e) {
      log.error(
          "Error occurred when processing the authorization request. Returning an error back to client.",
          e);
      OAuth2AuthorizeRespDTO authorizeRespDTO = new OAuth2AuthorizeRespDTO();
      authorizeRespDTO.setErrorCode(OAuth2ErrorCodes.SERVER_ERROR);
      authorizeRespDTO.setErrorMsg(
          "Error occurred when processing the authorization "
              + "request. Returning an error back to client.");
      authorizeRespDTO.setCallbackURI(oAuth2AuthorizeReqDTO.getCallbackUrl());
      return authorizeRespDTO;
    }
  }
Example #2
0
  @Override
  public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
      throws IdentityOAuth2Exception {
    OAuth2AccessTokenReqDTO oAuth2AccessTokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO();
    String username = oAuth2AccessTokenReqDTO.getResourceOwnerUsername();
    int tenantId;
    try {
      tenantId = IdentityUtil.getTenantIdOFUser(username);
    } catch (IdentityException e) {
      throw new IdentityOAuth2Exception(e.getMessage(), e);
    }

    // tenantId == -1, means an invalid tenant.
    if (tenantId == -1) {
      /*if (log.isDebugEnabled()) {
          log.debug("Token request with Password Grant Type for an invalid tenant : " +
                  MultitenantUtils.getTenantDomain(username));
      }
      return false;*/
      tenantId = MultitenantConstants.SUPER_TENANT_ID;
    }

    RealmService realmService = OAuthComponentServiceHolder.getRealmService();
    boolean authStatus;
    try {
      UserStoreManager userStoreManager =
          realmService.getTenantUserRealm(tenantId).getUserStoreManager();
      authStatus =
          userStoreManager.authenticate(
              MultitenantUtils.getTenantAwareUsername(username),
              oAuth2AccessTokenReqDTO.getResourceOwnerPassword());

      if (log.isDebugEnabled()) {
        log.debug(
            "Token request with Password Grant Type received. "
                + "Username : "******"Scope : "
                + OAuth2Util.buildScopeString(oAuth2AccessTokenReqDTO.getScope())
                + ", Authentication State : "
                + authStatus);
      }

    } catch (UserStoreException e) {
      throw new IdentityOAuth2Exception("Error when authenticating the user credentials.", e);
    }

    tokReqMsgCtx.setAuthorizedUser(oAuth2AccessTokenReqDTO.getResourceOwnerUsername());
    tokReqMsgCtx.setScope(oAuth2AccessTokenReqDTO.getScope());
    return authStatus;
  }
 private OAuth2AccessTokenRespDTO handleError(
     String errorCode, String errorMsg, OAuth2AccessTokenReqDTO tokenReqDTO) {
   if (log.isDebugEnabled()) {
     log.debug(
         "OAuth-Error-Code="
             + errorCode
             + " client-id="
             + tokenReqDTO.getClientId()
             + " grant-type="
             + tokenReqDTO.getGrantType()
             + " scope="
             + OAuth2Util.buildScopeString(tokenReqDTO.getScope()));
   }
   OAuth2AccessTokenRespDTO tokenRespDTO;
   tokenRespDTO = new OAuth2AccessTokenRespDTO();
   tokenRespDTO.setError(true);
   tokenRespDTO.setErrorCode(errorCode);
   tokenRespDTO.setErrorMsg(errorMsg);
   return tokenRespDTO;
 }
  /**
   * Revoke tokens issued to OAuth clients
   *
   * @param revokeRequestDTO DTO representing consumerKey, consumerSecret and tokens[]
   * @return revokeRespDTO DTO representing success or failure message
   */
  public OAuthRevocationResponseDTO revokeTokenByOAuthClient(
      OAuthRevocationRequestDTO revokeRequestDTO) {

    // fix here remove associated cache entry
    TokenMgtDAO tokenMgtDAO = new TokenMgtDAO();
    OAuthRevocationResponseDTO revokeResponseDTO = new OAuthRevocationResponseDTO();

    try {
      if (StringUtils.isNotEmpty(revokeRequestDTO.getConsumerKey())
          && StringUtils.isNotEmpty(revokeRequestDTO.getToken())) {

        boolean refreshTokenFirst = false;
        if (StringUtils.equals(
            GrantType.REFRESH_TOKEN.toString(), revokeRequestDTO.getToken_type())) {
          refreshTokenFirst = true;
        }

        RefreshTokenValidationDataDO refreshTokenDO = null;
        AccessTokenDO accessTokenDO = null;

        if (refreshTokenFirst) {

          refreshTokenDO =
              tokenMgtDAO.validateRefreshToken(
                  revokeRequestDTO.getConsumerKey(), revokeRequestDTO.getToken());

          if (refreshTokenDO == null
              || StringUtils.isEmpty(refreshTokenDO.getRefreshTokenState())
              || !(OAuthConstants.TokenStates.TOKEN_STATE_ACTIVE.equals(
                      refreshTokenDO.getRefreshTokenState())
                  || OAuthConstants.TokenStates.TOKEN_STATE_EXPIRED.equals(
                      refreshTokenDO.getRefreshTokenState()))) {

            accessTokenDO = tokenMgtDAO.retrieveAccessToken(revokeRequestDTO.getToken(), true);
            refreshTokenDO = null;
          }

        } else {
          accessTokenDO = tokenMgtDAO.retrieveAccessToken(revokeRequestDTO.getToken(), true);
          if (accessTokenDO == null) {

            refreshTokenDO =
                tokenMgtDAO.validateRefreshToken(
                    revokeRequestDTO.getConsumerKey(), revokeRequestDTO.getToken());

            if (refreshTokenDO == null
                || StringUtils.isEmpty(refreshTokenDO.getRefreshTokenState())
                || !(OAuthConstants.TokenStates.TOKEN_STATE_ACTIVE.equals(
                        refreshTokenDO.getRefreshTokenState())
                    || OAuthConstants.TokenStates.TOKEN_STATE_EXPIRED.equals(
                        refreshTokenDO.getRefreshTokenState()))) {
              return revokeResponseDTO;
            }
          }
        }

        String grantType = StringUtils.EMPTY;

        if (accessTokenDO != null) {
          grantType = accessTokenDO.getGrantType();
        } else if (refreshTokenDO != null) {
          grantType = refreshTokenDO.getGrantType();
        }

        if (!StringUtils.equals(OAuthConstants.GrantTypes.IMPLICIT, grantType)
            && !OAuth2Util.authenticateClient(
                revokeRequestDTO.getConsumerKey(), revokeRequestDTO.getConsumerSecret())) {

          OAuthRevocationResponseDTO revokeRespDTO = new OAuthRevocationResponseDTO();
          revokeRespDTO.setError(true);
          revokeRespDTO.setErrorCode(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
          revokeRespDTO.setErrorMsg("Unauthorized Client");

          return revokeRespDTO;
        }

        if (refreshTokenDO != null) {

          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(
              revokeRequestDTO.getConsumerKey(),
              refreshTokenDO.getAuthorizedUser(),
              OAuth2Util.buildScopeString(refreshTokenDO.getScope()));

          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(
              revokeRequestDTO.getConsumerKey(), refreshTokenDO.getAuthorizedUser());

          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(refreshTokenDO.getAccessToken());
          tokenMgtDAO.revokeTokens(new String[] {refreshTokenDO.getAccessToken()});

          addRevokeResponseHeaders(
              revokeResponseDTO,
              refreshTokenDO.getAccessToken(),
              revokeRequestDTO.getToken(),
              refreshTokenDO.getAuthorizedUser().toString());

        } else if (accessTokenDO != null) {
          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(
              revokeRequestDTO.getConsumerKey(),
              accessTokenDO.getAuthzUser(),
              OAuth2Util.buildScopeString(accessTokenDO.getScope()));
          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(
              revokeRequestDTO.getConsumerKey(), accessTokenDO.getAuthzUser());
          org.wso2.carbon.identity.oauth.OAuthUtil.clearOAuthCache(revokeRequestDTO.getToken());
          tokenMgtDAO.revokeTokens(new String[] {revokeRequestDTO.getToken()});
          addRevokeResponseHeaders(
              revokeResponseDTO,
              revokeRequestDTO.getToken(),
              accessTokenDO.getRefreshToken(),
              accessTokenDO.getAuthzUser().toString());
        }

        return revokeResponseDTO;

      } else {
        revokeResponseDTO.setError(true);
        revokeResponseDTO.setErrorCode(OAuth2ErrorCodes.INVALID_REQUEST);
        revokeResponseDTO.setErrorMsg("Invalid revocation request");
        return revokeResponseDTO;
      }

    } catch (InvalidOAuthClientException e) {
      log.error("Unauthorized Client", e);
      OAuthRevocationResponseDTO revokeRespDTO = new OAuthRevocationResponseDTO();
      revokeRespDTO.setError(true);
      revokeRespDTO.setErrorCode(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT);
      revokeRespDTO.setErrorMsg("Unauthorized Client");
      return revokeRespDTO;
    } catch (IdentityException e) {
      log.error("Error occurred while revoking authorization grant for applications", e);
      OAuthRevocationResponseDTO revokeRespDTO = new OAuthRevocationResponseDTO();
      revokeRespDTO.setError(true);
      revokeRespDTO.setErrorCode(OAuth2ErrorCodes.SERVER_ERROR);
      revokeRespDTO.setErrorMsg(
          "Error occurred while revoking authorization grant for applications");
      return revokeRespDTO;
    }
  }
  /**
   * Check Whether the provided client_id and the callback URL are valid.
   *
   * @param clientId client_id available in the request, Not null parameter.
   * @param callbackURI callback_uri available in the request, can be null.
   * @return <code>OAuth2ClientValidationResponseDTO</code> bean with validity information,
   *     callback, App Name, Error Code and Error Message when appropriate.
   */
  public OAuth2ClientValidationResponseDTO validateClientInfo(String clientId, String callbackURI) {
    OAuth2ClientValidationResponseDTO validationResponseDTO =
        new OAuth2ClientValidationResponseDTO();

    if (log.isDebugEnabled()) {
      log.debug(
          "Validate Client information request for client_id : "
              + clientId
              + " and callback_uri "
              + callbackURI);
    }

    try {
      OAuthAppDAO oAuthAppDAO = new OAuthAppDAO();
      OAuthAppDO appDO = oAuthAppDAO.getAppInformation(clientId);

      if (StringUtils.isEmpty(appDO.getGrantTypes())
          || StringUtils.isEmpty(appDO.getCallbackUrl())) {
        if (log.isDebugEnabled()) {
          log.debug(
              "Registered App found for the given Client Id : "
                  + clientId
                  + " ,App Name : "
                  + appDO.getApplicationName()
                  + ", does not support the requested grant type.");
        }
        validationResponseDTO.setValidClient(false);
        validationResponseDTO.setErrorCode(OAuth2ErrorCodes.UNSUPPORTED_GRANT_TYPE);
        validationResponseDTO.setErrorMsg("Requested Grant type is not supported.");
        return validationResponseDTO;
      }

      OAuth2Util.setClientTenatId(
          IdentityTenantUtil.getTenantId(appDO.getUser().getTenantDomain()));

      // Valid Client, No callback has provided. Use the callback provided during the registration.
      if (callbackURI == null) {
        validationResponseDTO.setValidClient(true);
        validationResponseDTO.setCallbackURL(appDO.getCallbackUrl());
        validationResponseDTO.setApplicationName(appDO.getApplicationName());
        return validationResponseDTO;
      }

      if (log.isDebugEnabled()) {
        log.debug(
            "Registered App found for the given Client Id : "
                + clientId
                + " ,App Name : "
                + appDO.getApplicationName()
                + ", Callback URL : "
                + appDO.getCallbackUrl());
      }

      // Valid Client with a callback url in the request. Check whether they are equal.
      if (appDO.getCallbackUrl().equals(callbackURI)) {
        validationResponseDTO.setValidClient(true);
        validationResponseDTO.setApplicationName(appDO.getApplicationName());
        validationResponseDTO.setCallbackURL(callbackURI);
        return validationResponseDTO;
      } else { // Provided callback URL does not match the registered callback url.
        log.warn("Provided Callback URL does not match with the provided one.");
        validationResponseDTO.setValidClient(false);
        validationResponseDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CALLBACK);
        validationResponseDTO.setErrorMsg(
            "Registered callback does not match with the provided url.");
        return validationResponseDTO;
      }
    } catch (InvalidOAuthClientException e) {
      // There is no such Client ID being registered. So it is a request from an invalid client.
      log.error("Error while retrieving the Application Information", e);
      validationResponseDTO.setValidClient(false);
      validationResponseDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT);
      validationResponseDTO.setErrorMsg(e.getMessage());
      return validationResponseDTO;
    } catch (IdentityOAuth2Exception e) {
      log.error("Error when reading the Application Information.", e);
      validationResponseDTO.setValidClient(false);
      validationResponseDTO.setErrorCode(OAuth2ErrorCodes.SERVER_ERROR);
      validationResponseDTO.setErrorMsg("Error when processing the authorization request.");
      return validationResponseDTO;
    }
  }
  public OAuth2AccessTokenRespDTO issue(OAuth2AccessTokenReqDTO tokenReqDTO)
      throws IdentityException, InvalidOAuthClientException {

    String grantType = tokenReqDTO.getGrantType();
    OAuth2AccessTokenRespDTO tokenRespDTO;

    AuthorizationGrantHandler authzGrantHandler = authzGrantHandlers.get(grantType);

    OAuthTokenReqMessageContext tokReqMsgCtx = new OAuthTokenReqMessageContext(tokenReqDTO);

    // If multiple client authentication methods have been used the authorization server must reject
    // the request
    int authenticatorHandlerIndex = -1;
    for (int i = 0; i < clientAuthenticationHandlers.size(); i++) {
      if (clientAuthenticationHandlers.get(i).canAuthenticate(tokReqMsgCtx)) {
        if (authenticatorHandlerIndex > -1) {
          log.debug(
              "Multiple Client Authentication Methods used for client id : "
                  + tokenReqDTO.getClientId());
          tokenRespDTO =
              handleError(
                  OAuthConstants.OAuthError.TokenResponse.UNSUPPORTED_CLIENT_AUTHENTICATION_METHOD,
                  "Unsupported Client Authentication Method!",
                  tokenReqDTO);
          setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
          return tokenRespDTO;
        }
        authenticatorHandlerIndex = i;
      }
    }
    if (authenticatorHandlerIndex < 0 && authzGrantHandler.isConfidentialClient()) {
      log.debug(
          "Confidential client cannot be authenticated for client id : "
              + tokenReqDTO.getClientId());
      tokenRespDTO =
          handleError(
              OAuthConstants.OAuthError.TokenResponse.UNSUPPORTED_CLIENT_AUTHENTICATION_METHOD,
              "Unsupported Client Authentication Method!",
              tokenReqDTO);
      setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
      return tokenRespDTO;
    }

    ClientAuthenticationHandler clientAuthHandler = null;
    if (authenticatorHandlerIndex > -1) {
      clientAuthHandler = clientAuthenticationHandlers.get(authenticatorHandlerIndex);
    }
    boolean isAuthenticated;
    if (clientAuthHandler != null) {
      isAuthenticated = clientAuthHandler.authenticateClient(tokReqMsgCtx);
    } else {
      isAuthenticated = true;
    }
    if (!isAuthenticated) {
      if (log.isDebugEnabled()) {
        log.debug("Client Authentication failed for client Id: " + tokenReqDTO.getClientId());
      }
      tokenRespDTO =
          handleError(
              OAuthError.TokenResponse.INVALID_CLIENT,
              "Client credentials are invalid.",
              tokenReqDTO);
      setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
      return tokenRespDTO;
    }

    // loading the stored application data
    OAuthAppDO oAuthAppDO = getAppInformation(tokenReqDTO);
    if (!authzGrantHandler.isOfTypeApplicationUser()) {
      tokReqMsgCtx.setAuthorizedUser(OAuth2Util.getUserFromUserName(oAuthAppDO.getUserName()));
      tokReqMsgCtx
          .getAuthorizedUser()
          .setTenantDomain(IdentityTenantUtil.getTenantDomain(oAuthAppDO.getTenantId()));
    }

    boolean isValidGrant = false;
    String error = "Provided Authorization Grant is invalid";
    try {
      isValidGrant = authzGrantHandler.validateGrant(tokReqMsgCtx);
    } catch (IdentityOAuth2Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Error occurred while validating grant", e);
      }
      error = e.getMessage();
    }

    if (!isValidGrant) {
      if (log.isDebugEnabled()) {
        log.debug("Invalid Grant provided by the client Id: " + tokenReqDTO.getClientId());
      }
      tokenRespDTO = handleError(OAuthError.TokenResponse.INVALID_GRANT, error, tokenReqDTO);
      setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
      return tokenRespDTO;
    }

    boolean isAuthorized = authzGrantHandler.authorizeAccessDelegation(tokReqMsgCtx);
    if (!isAuthorized) {
      if (log.isDebugEnabled()) {
        log.debug("Invalid authorization for client Id = " + tokenReqDTO.getClientId());
      }
      tokenRespDTO =
          handleError(
              OAuthError.TokenResponse.UNAUTHORIZED_CLIENT, "Unauthorized Client!", tokenReqDTO);
      setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
      return tokenRespDTO;
    }

    boolean isValidScope = authzGrantHandler.validateScope(tokReqMsgCtx);
    if (!isValidScope) {
      if (log.isDebugEnabled()) {
        log.debug("Invalid scope provided by client Id: " + tokenReqDTO.getClientId());
      }
      tokenRespDTO =
          handleError(OAuthError.TokenResponse.INVALID_SCOPE, "Invalid Scope!", tokenReqDTO);
      setResponseHeaders(tokReqMsgCtx, tokenRespDTO);
      return tokenRespDTO;
    }

    try {
      // set the token request context to be used by downstream handlers. This is introduced as a
      // fix for
      // IDENTITY-4111.
      OAuth2Util.setTokenRequestContext(tokReqMsgCtx);
      tokenRespDTO = authzGrantHandler.issue(tokReqMsgCtx);
    } finally {
      // clears the token request context.
      OAuth2Util.clearTokenRequestContext();
    }

    tokenRespDTO.setCallbackURI(oAuthAppDO.getCallbackUrl());

    String[] scopes = tokReqMsgCtx.getScope();
    if (scopes != null && scopes.length > 0) {
      StringBuilder scopeString = new StringBuilder("");
      for (String scope : scopes) {
        scopeString.append(scope);
        scopeString.append(" ");
      }
      tokenRespDTO.setAuthorizedScopes(scopeString.toString().trim());
    }

    setResponseHeaders(tokReqMsgCtx, tokenRespDTO);

    // Do not change this log format as these logs use by external applications
    if (log.isDebugEnabled()) {
      log.debug(
          "Access token issued to client Id: "
              + tokenReqDTO.getClientId()
              + " username: "******" and scopes: "
              + tokenRespDTO.getAuthorizedScopes());
    }

    if (tokReqMsgCtx.getScope() != null && OAuth2Util.isOIDCAuthzRequest(tokReqMsgCtx.getScope())) {
      IDTokenBuilder builder =
          OAuthServerConfiguration.getInstance().getOpenIDConnectIDTokenBuilder();
      tokenRespDTO.setIDToken(builder.buildIDToken(tokReqMsgCtx, tokenRespDTO));
    }

    if (tokenReqDTO.getGrantType().equals(GrantType.AUTHORIZATION_CODE.toString())) {
      addUserAttributesToCache(tokenReqDTO, tokenRespDTO);
    }

    return tokenRespDTO;
  }