private AccessTokenIssuer() throws IdentityOAuth2Exception {

    authzGrantHandlers = OAuthServerConfiguration.getInstance().getSupportedGrantTypes();
    clientAuthenticationHandlers =
        OAuthServerConfiguration.getInstance().getSupportedClientAuthHandlers();
    appInfoCache = AppInfoCache.getInstance();
    if (appInfoCache != null) {
      if (log.isDebugEnabled()) {
        log.debug("Successfully created AppInfoCache under " + OAuthConstants.OAUTH_CACHE_MANAGER);
      }
    } else {
      log.error("Error while creating AppInfoCache");
    }
  }
  public String buildIDToken(
      OAuthTokenReqMessageContext request, OAuth2AccessTokenRespDTO tokenRespDTO)
      throws IdentityOAuth2Exception {
    OAuthServerConfiguration config = OAuthServerConfiguration.getInstance();
    String issuer = config.getOpenIDConnectIDTokenIssuerIdentifier();
    int lifetime = Integer.parseInt(config.getOpenIDConnectIDTokenExpiration()) * 1000;
    int curTime = (int) Calendar.getInstance().getTimeInMillis();
    // setting subject
    String subject = request.getAuthorizedUser();
    String claim = config.getOpenIDConnectIDTokenSubjectClaim();
    if (claim != null) {
      String tenantUser = MultitenantUtils.getTenantAwareUsername(request.getAuthorizedUser());
      String domainName = MultitenantUtils.getTenantDomain(request.getAuthorizedUser());
      try {
        subject =
            IdentityTenantUtil.getRealm(domainName, tenantUser)
                .getUserStoreManager()
                .getUserClaimValue(tenantUser, claim, null);
      } catch (Exception e) {
        throw new IdentityOAuth2Exception("Erro while generating the IDToken", e);
      }
    }

    if (DEBUG) {
      log.debug("Using issuer " + issuer);
      log.debug("Subject " + subject);
      log.debug("ID Token expiration seconds" + lifetime);
      log.debug("Current time " + curTime);
    }

    try {
      IDTokenBuilder builder =
          new IDTokenBuilder()
              .setIssuer(issuer)
              .setSubject(subject)
              .setAudience(request.getOauth2AccessTokenReqDTO().getClientId())
              .setAuthorizedParty(request.getOauth2AccessTokenReqDTO().getClientId())
              .setExpiration(curTime + lifetime)
              .setIssuedAt(curTime);
      // setting up custom claims
      CustomClaimsCallbackHandler claimsCallBackHandler =
          OAuthServerConfiguration.getInstance().getOpenIDConnectCustomClaimsCallbackHandler();
      claimsCallBackHandler.handleCustomClaims(builder, request);
      return builder.buildIDToken();
    } catch (IDTokenException e) {
      throw new IdentityOAuth2Exception("Erro while generating the IDToken", e);
    }
  }
  /**
   * Initialize a grant type validator
   *
   * @return an instance of OAuthValidator
   * @throws OAuthProblemException
   * @throws OAuthSystemException
   */
  @Override
  protected OAuthValidator<HttpServletRequest> initValidator()
      throws OAuthProblemException, OAuthSystemException {

    String requestTypeValue = getParam(OAuth.OAUTH_GRANT_TYPE);
    if (OAuthUtils.isEmpty(requestTypeValue)) {
      throw OAuthUtils.handleOAuthProblemException("Missing grant_type parameter value");
    }

    Class<? extends OAuthValidator<HttpServletRequest>> clazz =
        OAuthServerConfiguration.getInstance()
            .getSupportedGrantTypeValidators()
            .get(requestTypeValue);

    if (clazz == null) {
      if (log.isDebugEnabled()) {
        // Do not change this log format as these logs use by external applications
        log.debug(
            "Unsupported Grant Type : " + requestTypeValue + " for client id : " + getClientId());
      }
      throw OAuthUtils.handleOAuthProblemException("Invalid grant_type parameter value");
    }

    return OAuthUtils.instantiateClass(clazz);
  }
 /**
  * Reads the DialectURI of the ClaimURIs to be retrieved from identity.xml -> OAuth ->
  * TokenGeneration -> ConsumerDialectURI. If not configured it uses http://wso2.org/claims as
  * default
  */
 @Override
 public void init() {
   dialectURI = OAuthServerConfiguration.getInstance().getConsumerDialectURI();
   if (dialectURI == null) {
     dialectURI = DEFAULT_DIALECT_URI;
   }
   claimsLocalCache = ClaimCache.getInstance();
 }
Beispiel #5
0
  public OAuthAppDAO() {

    try {
      tokenPersistenceProcessor =
          OAuthServerConfiguration.getInstance().getTokenPersistenceProcessor();
    } catch (IdentityOAuth2Exception e) {
      log.error("Error retrieving TokenPersistenceProcessor. Defaulting to PlainTextProcessor");
      tokenPersistenceProcessor = new PlainTextProcessor();
    }
  }
  /**
   * Returns an array of claims of the authorized user. This is for the OpenIDConnect user-end-point
   * implementation.
   *
   * <p>TODO : 1. Should return the userinfo response instead. TODO : 2. Should create another
   * service API for userinfo endpoint
   *
   * @param accessTokenIdentifier
   * @return
   * @throws IdentityException
   */
  public Claim[] getUserClaims(String accessTokenIdentifier) {

    OAuth2TokenValidationRequestDTO reqDTO = new OAuth2TokenValidationRequestDTO();
    OAuth2TokenValidationRequestDTO.OAuth2AccessToken accessToken = reqDTO.new OAuth2AccessToken();
    accessToken.setTokenType("bearer");
    accessToken.setIdentifier(accessTokenIdentifier);
    reqDTO.setAccessToken(accessToken);
    OAuth2TokenValidationResponseDTO respDTO = new OAuth2TokenValidationService().validate(reqDTO);

    String username = respDTO.getAuthorizedUser();
    if (username == null) { // invalid token
      log.debug(respDTO.getErrorMsg());
      return new Claim[0];
    }
    String[] scope = respDTO.getScope();
    boolean isOICScope = false;
    for (String curScope : scope) {
      if ("openid".equals(curScope)) {
        isOICScope = true;
      }
    }
    if (!isOICScope) {
      log.error("AccessToken does not have the openid scope");
      return new Claim[0];
    }

    // TODO : this code is ugly
    String profileName = "default"; // TODO : configurable
    String tenantDomain = MultitenantUtils.getTenantDomain(username);
    String tenatUser = MultitenantUtils.getTenantAwareUsername(username);

    List<Claim> claimsList = new ArrayList<Claim>();

    // MUST claim
    // http://openid.net/specs/openid-connect-basic-1_0-22.html#id_res
    Claim subClaim = new Claim();
    subClaim.setClaimUri("sub");
    subClaim.setValue(username);
    claimsList.add(subClaim);

    try {
      UserStoreManager userStore =
          IdentityTenantUtil.getRealm(tenantDomain, tenatUser).getUserStoreManager();
      // externel configured claims
      String[] claims = OAuthServerConfiguration.getInstance().getSupportedClaims();
      if (claims != null) {
        Map<String, String> extClaimsMap =
            userStore.getUserClaimValues(username, claims, profileName);
        for (Map.Entry<String, String> entry : extClaimsMap.entrySet()) {
          Claim curClaim = new Claim();
          curClaim.setClaimUri(entry.getKey());
          curClaim.setValue(entry.getValue());
          claimsList.add(curClaim);
        }
      }
      // default claims
      String[] defaultClaims = new String[3];
      defaultClaims[0] = "http://wso2.org/claims/emailaddress";
      defaultClaims[1] = "http://wso2.org/claims/givenname";
      defaultClaims[2] = "http://wso2.org/claims/lastname";
      String emailAddress = null;
      String firstName = null;
      String lastName = null;
      Map<String, String> defClaimsMap =
          userStore.getUserClaimValues(username, defaultClaims, profileName);
      if (defClaimsMap.get(defaultClaims[0]) != null) {
        emailAddress = defClaimsMap.get(defaultClaims[0]);
        Claim email = new Claim();
        email.setClaimUri("email");
        email.setValue(emailAddress);
        claimsList.add(email);
        Claim prefName = new Claim();
        prefName.setClaimUri("preferred_username");
        prefName.setValue(emailAddress.split("@")[0]);
        claimsList.add(prefName);
      }
      if (defClaimsMap.get(defaultClaims[1]) != null) {
        firstName = defClaimsMap.get(defaultClaims[1]);
        Claim givenName = new Claim();
        givenName.setClaimUri("given_name");
        givenName.setValue(firstName);
        claimsList.add(givenName);
      }
      if (defClaimsMap.get(defaultClaims[2]) != null) {
        lastName = defClaimsMap.get(defaultClaims[2]);
        Claim familyName = new Claim();
        familyName.setClaimUri("family_name");
        familyName.setValue(lastName);
        claimsList.add(familyName);
      }
      if (firstName != null && lastName != null) {
        Claim name = new Claim();
        name.setClaimUri("name");
        name.setValue(firstName + " " + lastName);
        claimsList.add(name);
      }

    } catch (Exception e) {
      log.error("Error while reading user claims ", e);
    }

    Claim[] allClaims = new Claim[claimsList.size()];
    for (int i = 0; i < claimsList.size(); i++) {
      allClaims[i] = claimsList.get(i);
    }
    return allClaims;
  }
  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;
  }