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