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