예제 #1
0
  public OAuthAppDO getAppInformation(String consumerKey)
      throws InvalidOAuthClientException, IdentityOAuth2Exception {
    Connection connection = null;
    PreparedStatement prepStmt = null;
    ResultSet rSet = null;
    OAuthAppDO oauthApp = null;

    try {
      connection = JDBCPersistenceManager.getInstance().getDBConnection();
      prepStmt = connection.prepareStatement(SQLQueries.OAuthAppDAOSQLQueries.GET_APP_INFO);
      prepStmt.setString(1, tokenPersistenceProcessor.getProcessedToken(consumerKey));

      rSet = prepStmt.executeQuery();
      List<OAuthAppDO> oauthApps = new ArrayList<OAuthAppDO>();
      /**
       * We need to determine whether the result set has more than 1 row. Meaning, we found an
       * application for the given consumer key. There can be situations where a user passed a key
       * which doesn't yet have an associated application. We need to barf with a meaningful error
       * message for this case
       */
      boolean rSetHasRows = false;
      while (rSet.next()) {
        // There is at least one application associated with a given key
        rSetHasRows = true;
        if (rSet.getString(4) != null && rSet.getString(4).length() > 0) {
          oauthApp = new OAuthAppDO();
          oauthApp.setOauthConsumerKey(consumerKey);
          oauthApp.setOauthConsumerSecret(
              tokenPersistenceProcessor.getPreprocessedToken(rSet.getString(1)));
          oauthApp.setUserName(rSet.getString(2));
          oauthApp.setApplicationName(rSet.getString(3));
          oauthApp.setOauthVersion(rSet.getString(4));
          oauthApp.setCallbackUrl(rSet.getString(5));
          oauthApp.setTenantId(rSet.getInt(6));
          oauthApp.setGrantTypes(rSet.getString(7));
          oauthApps.add(oauthApp);
        }
      }
      if (!rSetHasRows) {
        /**
         * We come here because user submitted a key that doesn't have any associated application
         * with it. We're throwing an error here because we cannot continue without this info.
         * Otherwise it'll throw a null values not supported error when it tries to cache this info
         */
        String message =
            "Cannot find an application associated with the given consumer key : " + consumerKey;
        log.debug(message);
        throw new InvalidOAuthClientException(message);
      }
    } catch (IdentityException e) {
      log.debug(e.getMessage(), e);
      throw new IdentityOAuth2Exception(e.getMessage());
    } catch (SQLException e) {
      log.debug(e.getMessage(), e);
      throw new IdentityOAuth2Exception(e.getMessage());
    } finally {
      IdentityDatabaseUtil.closeAllConnections(connection, rSet, prepStmt);
    }
    return oauthApp;
  }
  @Override
  public boolean doPostUpdateCredential(
      String userName, Object credential, UserStoreManager userStoreManager)
      throws UserStoreException {

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();

    UserIdentityClaimsDO userIdentityDTO = module.load(userName, userStoreManager);

    if (userIdentityDTO == null) {
      userIdentityDTO = new UserIdentityClaimsDO(userName);
    }

    // Do not timestamp if OTP enabled.
    boolean userOTPEnabled = userIdentityDTO.getOneTimeLogin();

    if (config.isAuthPolicyExpirePasswordCheck()
        && !userOTPEnabled
        && (!userStoreManager.isReadOnly())) {

      Calendar currentTime = Calendar.getInstance();
      userIdentityDTO.setPasswordTimeStamp(Calendar.getInstance().getTimeInMillis());

      try {
        // Store the new timestamp after change password
        module.store(userIdentityDTO, userStoreManager);

      } catch (IdentityException e) {
        throw new UserStoreException(e.getMessage());
      }
    }

    return true;
  }
  @Override
  public SignableXMLObject setSignature(
      SignableXMLObject signableXMLObject,
      String signatureAlgorithm,
      String digestAlgorithm,
      X509Credential cred)
      throws IdentityException {

    Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME);
    signature.setSigningCredential(cred);
    signature.setSignatureAlgorithm(signatureAlgorithm);
    signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);

    KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
    X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME);
    X509Certificate cert = (X509Certificate) buildXMLObject(X509Certificate.DEFAULT_ELEMENT_NAME);

    String value;
    try {
      value = org.apache.xml.security.utils.Base64.encode(cred.getEntityCertificate().getEncoded());
    } catch (CertificateEncodingException e) {
      throw IdentityException.error("Error occurred while retrieving encoded cert", e);
    }

    cert.setValue(value);
    data.getX509Certificates().add(cert);
    keyInfo.getX509Datas().add(data);
    signature.setKeyInfo(keyInfo);

    signableXMLObject.setSignature(signature);
    ((SAMLObjectContentReference) signature.getContentReferences().get(0))
        .setDigestAlgorithm(digestAlgorithm);

    List<Signature> signatureList = new ArrayList<Signature>();
    signatureList.add(signature);

    MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory();
    Marshaller marshaller = marshallerFactory.getMarshaller(signableXMLObject);

    try {
      marshaller.marshall(signableXMLObject);
    } catch (MarshallingException e) {
      throw IdentityException.error("Unable to marshall the request", e);
    }

    org.apache.xml.security.Init.init();
    try {
      Signer.signObjects(signatureList);
    } catch (SignatureException e) {
      throw IdentityException.error("Error occurred while signing request", e);
    }

    return signableXMLObject;
  }
예제 #4
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;
  }
  /**
   * @param ppid
   * @throws IdentityException
   */
  public void registerOAuthConsumer(OAuthConsumerDO consumer) throws IdentityException {

    Collection userResource = null;

    if (log.isDebugEnabled()) {
      log.debug("Creating or updating OAuth consumer value");
    }

    try {

      boolean transactionStarted = Transaction.isStarted();
      try {
        if (!transactionStarted) {
          registry.beginTransaction();
        }

        if (!registry.resourceExists(RegistryConstants.PROFILES_PATH + consumer.getConsumerKey())) {
          userResource = registry.newCollection();
          registry.put(RegistryConstants.PROFILES_PATH + consumer.getConsumerKey(), userResource);
        } else {
          userResource =
              (Collection)
                  registry.get(RegistryConstants.PROFILES_PATH + consumer.getConsumerKey());
          userResource.removeProperty(IdentityRegistryResources.OAUTH_CONSUMER_PATH);
        }

        userResource.addProperty(
            IdentityRegistryResources.OAUTH_CONSUMER_PATH, consumer.getConsumerSecret());

        registry.put(RegistryConstants.PROFILES_PATH + consumer.getConsumerKey(), userResource);
        if (!transactionStarted) {
          registry.commitTransaction();
        }
      } catch (Exception e) {
        if (!transactionStarted) {
          registry.rollbackTransaction();
        }
        if (e instanceof RegistryException) {
          throw (RegistryException) e;
        } else {
          throw IdentityException.error("Error while creating or updating OAuth consumer", e);
        }
      }
    } catch (RegistryException e) {
      log.error("Error while creating or updating OAuth consumer", e);
      throw IdentityException.error("Error while creating or updating OAuth consumer", e);
    }
  }
 /**
  * Builds SAML Elements
  *
  * @param objectQName
  * @return
  * @throws IdentityException
  */
 private XMLObject buildXMLObject(QName objectQName) throws IdentityException {
   XMLObjectBuilder builder =
       org.opensaml.xml.Configuration.getBuilderFactory().getBuilder(objectQName);
   if (builder == null) {
     throw IdentityException.error("Unable to retrieve builder for object QName " + objectQName);
   }
   return builder.buildObject(
       objectQName.getNamespaceURI(), objectQName.getLocalPart(), objectQName.getPrefix());
 }
  /**
   * Validates the authentication request according to IdP Initiated SAML SSO Web Browser
   * Specification
   *
   * @return SAMLSSOSignInResponseDTO
   * @throws org.wso2.carbon.identity.base.IdentityException
   */
  public SAMLSSOReqValidationResponseDTO validate() throws IdentityException {

    SAMLSSOReqValidationResponseDTO validationResponse = new SAMLSSOReqValidationResponseDTO();
    try {

      // spEntityID MUST NOT be null
      if (StringUtils.isNotBlank(spEntityID)) {
        validationResponse.setIssuer(spEntityID);
      } else {
        String errorResp =
            SAMLSSOUtil.buildErrorResponse(
                SAMLSSOConstants.StatusCodes.REQUESTOR_ERROR,
                "spEntityID parameter not found in request",
                null);
        if (log.isDebugEnabled()) {
          log.debug("spEntityID parameter not found in request");
        }
        validationResponse.setResponse(errorResp);
        validationResponse.setValid(false);
        return validationResponse;
      }

      if (!SAMLSSOUtil.isSAMLIssuerExists(
          spEntityID, SAMLSSOUtil.getTenantDomainFromThreadLocal())) {
        String message =
            "A Service Provider with the Issuer '"
                + spEntityID
                + "' is not registered. Service "
                + "Provider should be registered in advance";
        log.error(message);
        String errorResp =
            SAMLSSOUtil.buildErrorResponse(
                SAMLSSOConstants.StatusCodes.REQUESTOR_ERROR, message, null);
        validationResponse.setResponse(errorResp);
        validationResponse.setValid(false);
        return validationResponse;
      }

      // If SP has multiple ACS
      if (StringUtils.isNotBlank(acs)) {
        validationResponse.setAssertionConsumerURL(acs);
      }

      if (StringUtils.isBlank(SAMLSSOUtil.getTenantDomainFromThreadLocal())) {
        SAMLSSOUtil.setTenantDomainInThreadLocal(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
      }

      validationResponse.setValid(true);

      if (log.isDebugEnabled()) {
        log.debug("IdP Initiated SSO request validation is successful");
      }
      return validationResponse;
    } catch (Exception e) {
      throw IdentityException.error("Error validating the IdP Initiated SSO request", e);
    }
  }
  @Override
  public boolean validateXMLSignature(
      RequestAbstractType request, X509Credential cred, String alias) throws IdentityException {

    boolean isSignatureValid = false;

    if (request.getSignature() != null) {
      try {
        SignatureValidator validator = new SignatureValidator(cred);
        validator.validate(request.getSignature());
        isSignatureValid = true;
      } catch (ValidationException e) {
        throw IdentityException.error(
            "Signature Validation Failed for the SAML Assertion : Signature is " + "invalid.", e);
      }
    }
    return isSignatureValid;
  }
  /**
   * @param ppid
   * @return
   * @throws IdentityException
   */
  public String getOAuthConsumerSecret(String consumerKey) throws IdentityException {
    String path = null;
    Resource resource = null;

    if (log.isDebugEnabled()) {
      log.debug("Retreiving user for OAuth consumer key  " + consumerKey);
    }

    try {
      path = RegistryConstants.PROFILES_PATH + consumerKey;
      if (registry.resourceExists(path)) {
        resource = registry.get(path);
        return resource.getProperty(IdentityRegistryResources.OAUTH_CONSUMER_PATH);
      } else {
        return null;
      }
    } catch (RegistryException e) {
      log.error("Error while retreiving user for OAuth consumer key  " + consumerKey, e);
      throw IdentityException.error(
          "Error while retreiving user for OAuth consumer key  " + consumerKey, e);
    }
  }
  /**
   * This method locks the created accounts based on the account policies or based on the account
   * confirmation method being used. Two account confirmation methods are used : Temporary Password
   * and Verification Code. In the case of temporary password is used the temporary password will be
   * emailed to the user. In the case of verification code, the code will be emailed to the user.
   * The security questions filter ad doPreAddUser will be persisted in this method.
   */
  @Override
  public boolean doPostAddUser(
      String userName,
      Object credential,
      String[] roleList,
      Map<String, String> claims,
      String profile,
      UserStoreManager userStoreManager)
      throws UserStoreException {
    if (log.isDebugEnabled()) {
      log.debug("Post add user is called in IdentityMgtEventListener");
    }
    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }
    // reading the value from the thread local
    UserIdentityClaimsDO userIdentityClaimsDO =
        (UserIdentityClaimsDO) threadLocalProperties.get().get(USER_IDENTITY_DO);

    if (config.isEnableUserAccountVerification()) {

      // empty password account creation
      if (threadLocalProperties.get().containsKey(EMPTY_PASSWORD_USED)) {
        // store identity data
        userIdentityClaimsDO.setAccountLock(false).setPasswordTimeStamp(System.currentTimeMillis());
        try {
          module.store(userIdentityClaimsDO, userStoreManager);
        } catch (IdentityException e) {
          throw new UserStoreException("Error while doPostAddUser", e);
        }
        // store identity metadata
        UserRecoveryDataDO metadataDO = new UserRecoveryDataDO();
        metadataDO
            .setUserName(userName)
            .setTenantId(userStoreManager.getTenantId())
            .setCode((String) credential);
        //				try {
        //	                UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO);
        //                } catch (IdentityException e) {
        //                	throw new UserStoreException("Error while doPreAddUser", e);
        //                }

        // set recovery data
        RecoveryProcessor processor = new RecoveryProcessor();
        VerificationBean verificationBean = new VerificationBean();

        try {
          verificationBean =
              processor.updateConfirmationCode(1, userName, userStoreManager.getTenantId());
        } catch (IdentityException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

        // preparing a bean to send the email
        UserIdentityMgtBean bean = new UserIdentityMgtBean();
        bean.setUserId(userName)
            .setConfirmationCode(verificationBean.getKey())
            .setRecoveryType(IdentityMgtConstants.Notification.TEMPORARY_PASSWORD)
            .setEmail(claims.get(config.getAccountRecoveryClaim()));

        UserRecoveryDTO recoveryDto = new UserRecoveryDTO(userName);
        recoveryDto.setNotification(IdentityMgtConstants.Notification.ASK_PASSWORD);
        recoveryDto.setNotificationType("EMAIL");
        recoveryDto.setTenantId(userStoreManager.getTenantId());
        recoveryDto.setConfirmationCode(verificationBean.getKey());

        NotificationDataDTO notificationDto = null;

        try {
          notificationDto = processor.recoverWithNotification(recoveryDto);
        } catch (IdentityException e) {
          if (log.isDebugEnabled()) {
            log.debug(e.getMessage());
          }
          throw new UserStoreException("Error while sending notification. " + e.getMessage());
        }

        if (notificationDto != null && notificationDto.isNotificationSent()) {
          return true;
        } else {
          return false;
        }

        // sending email
        //				UserIdentityManagementUtil.notifyViaEmail(bean);

      } else {
        // none-empty passwords. lock account and persist
        /*				This scenario needs to be validated.
        * 				userIdentityClaimsDO.setAccountLock(true)
        			                    .setPasswordTimeStamp(System.currentTimeMillis());
        			try {
        				UserIdentityManagementUtil.storeUserIdentityClaims(userIdentityClaimsDO, userStoreManager);
        			} catch (IdentityException e) {
        				throw new UserStoreException("Error while doPostAddUser", e);
        			}
        			String confirmationCode = UserIdentityManagementUtil.generateRandomConfirmationCode();
        			// store identity metadata
        			UserRecoveryDataDO metadataDO = new UserRecoveryDataDO();
        			metadataDO.setUserName(userName).setTenantId(userStoreManager.getTenantId())
        			          .setCode(confirmationCode);
        			try {
                        UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO);
                       } catch (IdentityException e) {
                       	throw new UserStoreException("Error while doPostAddUser", e);
                       }
        			// sending a mail with the confirmation code
        			UserIdentityMgtBean bean = new UserIdentityMgtBean();
        			bean.setUserId(userName)
        			    .setRecoveryType(IdentityMgtConstants.Notification.ACCOUNT_CONFORM)
        			    .setConfirmationCode(confirmationCode);
        			UserIdentityManagementUtil.notifyViaEmail(bean);
        			return true; */
      }
    }
    // No account recoveries are defined, no email will be sent.
    if (config.isAuthPolicyAccountLockOnCreation()) {
      // accounts are locked. Admin should unlock
      userIdentityClaimsDO.setAccountLock(true);
      userIdentityClaimsDO.setPasswordTimeStamp(System.currentTimeMillis());
      try {
        config.getIdentityDataStore().store(userIdentityClaimsDO, userStoreManager);
      } catch (IdentityException e) {
        throw new UserStoreException("Error while doPostAddUser", e);
      }
    }
    return true;
  }