use of org.wso2.carbon.identity.oauth2.IdentityOAuth2ClientException in project identity-inbound-auth-oauth by wso2-extensions.
the class OIDCLogoutServlet method doGet.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* Recommended Parameter : id_token_hint
* As per the specification https://openid.net/specs/openid-connect-session-1_0.html#RFC6454, it's recommended
* to expect id_token_hint parameter to determine which RP initiated the logout request.
* Otherwise, it could lead to DoS attacks. Thus, at least explicit user confirmation is needed to act upon
* such logout requests.
*
* Optional Parameter : post_logout_redirect_uri
* This denotes the RP URL to be redirected after logout has been performed. This value must be previously
* registered at IdP via post_logout_redirect_uris registration parameter or by some other configuration. And
* the received URL should be validated to be one of registered.
*/
/**
* todo: At the moment we do not persist id_token issued for clients, thus we could not retrieve the RP that
* todo: a specific id_token has been issued.
* todo: Since we use a browser cookie to track the session, for the moment, we
* todo: will validate if the logout request is being initiated by an active session via the cookie
* todo: This need to be fixed such that we do not rely on the cookie and the request is validated against
* todo: the id_token_hint received
*
* todo: Should provide a way to register post_logout_redirect_uris at IdP and should validate the received
* todo: parameter against the set of registered values. This depends on retrieving client for the received
* todo: id_token_hint value
*/
String redirectURL;
String opBrowserState = getOPBrowserState(request);
if (StringUtils.isBlank(opBrowserState)) {
String msg = OIDCSessionConstants.OPBS_COOKIE_ID + " cookie not received. Missing session state.";
if (log.isDebugEnabled()) {
log.debug(msg);
}
if (OIDCSessionManagementUtil.handleAlreadyLoggedOutSessionsGracefully()) {
handleMissingSessionStateGracefully(request, response);
return;
} else {
if (log.isDebugEnabled()) {
msg = "HandleAlreadyLoggedOutSessionsGracefully configuration disabled. Missing session state is " + "handled by redirecting to error page instead of default logout page.";
log.debug(msg);
}
redirectURL = getErrorPageURL(OAuth2ErrorCodes.ACCESS_DENIED, msg);
response.sendRedirect(getRedirectURL(redirectURL, request));
return;
}
}
if (!OIDCSessionManagementUtil.getSessionManager().sessionExists(opBrowserState, OAuth2Util.resolveTenantDomain(request))) {
String msg = "No valid session found for the received session state.";
if (log.isDebugEnabled()) {
log.debug(msg);
}
OIDCSessionManagementUtil.removeOPBrowserStateCookie(request, response);
if (OIDCSessionManagementUtil.handleAlreadyLoggedOutSessionsGracefully()) {
handleMissingSessionStateGracefully(request, response);
} else {
if (log.isDebugEnabled()) {
msg = "HandleAlreadyLoggedOutSessionsGracefully configuration enabled. No valid session found is " + "handled by redirecting to error page instead of default logout page.";
log.debug(msg);
}
redirectURL = getErrorPageURL(OAuth2ErrorCodes.ACCESS_DENIED, msg);
response.sendRedirect(getRedirectURL(redirectURL, request));
}
return;
}
String consent = request.getParameter(OIDCSessionConstants.OIDC_LOGOUT_CONSENT_PARAM);
if (StringUtils.isNotBlank(consent)) {
// User consent received for logout
if (consent.equals(OAuthConstants.Consent.APPROVE)) {
// User approved logout. Logout from authentication framework
sendToFrameworkForLogout(request, response);
return;
} else {
// User denied logout.
redirectURL = getErrorPageURL(OAuth2ErrorCodes.ACCESS_DENIED, "End User denied the logout request");
// If postlogoutUri is available then set it as redirectUrl
redirectURL = generatePostLogoutRedirectUrl(redirectURL, opBrowserState, request);
response.sendRedirect(redirectURL);
return;
}
} else {
// OIDC Logout response
String sessionDataKey = request.getParameter(OIDCSessionConstants.OIDC_SESSION_DATA_KEY_PARAM);
if (sessionDataKey != null) {
handleLogoutResponseFromFramework(request, response);
return;
}
String idTokenHint = request.getParameter(OIDCSessionConstants.OIDC_ID_TOKEN_HINT_PARAM);
boolean skipConsent;
// Get user consent to logout
try {
skipConsent = getOpenIDConnectSkipUserConsent(request);
} catch (ParseException e) {
if (log.isDebugEnabled()) {
log.debug("Error while getting clientId from the IdTokenHint.", e);
}
redirectURL = getErrorPageURL(OAuth2ErrorCodes.ACCESS_DENIED, "ID token signature validation failed.");
response.sendRedirect(getRedirectURL(redirectURL, request));
return;
} catch (IdentityOAuth2ClientException e) {
if (log.isDebugEnabled()) {
log.debug("Error while getting service provider from the clientId.", e);
}
redirectURL = getErrorPageURL(OAuth2ErrorCodes.ACCESS_DENIED, "ID token signature validation failed.");
response.sendRedirect(getRedirectURL(redirectURL, request));
return;
} catch (IdentityOAuth2Exception e) {
log.error("Error occurred while getting oauth application information.", e);
return;
}
if (skipConsent) {
if (StringUtils.isNotBlank(idTokenHint)) {
redirectURL = processLogoutRequest(request, response);
if (StringUtils.isNotBlank(redirectURL)) {
response.sendRedirect(getRedirectURL(redirectURL, request));
return;
}
} else {
// Add OIDC Cache entry without properties since OIDC Logout should work without id_token_hint
OIDCSessionDataCacheEntry cacheEntry = new OIDCSessionDataCacheEntry();
/*
Logout request without id_token_hint will redirected to an IDP's page once logged out, rather a
RP's callback endpoint. The state parameter is set here in the cache, so that it will be
available in the redirected IDP's page to support any custom requirement.
*/
setStateParameterInCache(request, cacheEntry);
addSessionDataToCache(opBrowserState, cacheEntry);
}
sendToFrameworkForLogout(request, response);
return;
} else {
sendToConsentUri(request, response);
return;
}
}
}
use of org.wso2.carbon.identity.oauth2.IdentityOAuth2ClientException in project identity-inbound-auth-oauth by wso2-extensions.
the class ScopeClaimMappingDAOImpl method addScopes.
@Override
public void addScopes(int tenantId, List<ScopeDTO> scopeClaimsList) throws IdentityOAuth2Exception {
JdbcTemplate jdbcTemplate = JdbcUtils.getNewTemplate();
scopeClaimsList.forEach(rethrowConsumer(scopeDTO -> {
String scope = scopeDTO.getName();
String[] claims = scopeDTO.getClaim();
// name is exist will throw conflict error.
if (!isScopeExist(scope, tenantId, true)) {
try {
int scopeClaimMappingId = jdbcTemplate.executeInsert(SQLQueries.STORE_IDN_OAUTH2_SCOPE, (preparedStatement -> {
preparedStatement.setString(1, scope);
preparedStatement.setString(2, scopeDTO.getDisplayName());
preparedStatement.setString(3, scopeDTO.getDescription());
preparedStatement.setInt(4, tenantId);
preparedStatement.setString(5, Oauth2ScopeConstants.SCOPE_TYPE_OIDC);
}), null, true, Oauth2ScopeConstants.SCOPE_ID);
if (scopeClaimMappingId > 0 && ArrayUtils.isNotEmpty(claims)) {
Set<String> claimsSet = new HashSet<>(Arrays.asList(claims));
insertClaims(tenantId, scopeClaimMappingId, claimsSet);
}
if (log.isDebugEnabled() && ArrayUtils.isNotEmpty(claims)) {
log.debug("The scope: " + scope + " and the claims: " + Arrays.asList(claims) + "are " + "successfully inserted for the tenant: " + tenantId);
}
} catch (DataAccessException e) {
if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
int scopeClaimMappingId = getScopeId(scope, tenantId);
if (scopeClaimMappingId > 0) {
log.warn("Scope " + scope + " already exist in tenant " + tenantId + " , hence ignoring");
return;
}
} else {
String errorMessage = "Error while persisting new claims for the scope for the tenant: " + tenantId;
throw new IdentityOAuth2Exception(errorMessage, e);
}
}
} else {
log.warn(String.format("Scope %s already exist in tenant %s.", scope, tenantId));
throw new IdentityOAuth2ClientException(Oauth2ScopeConstants.ErrorMessages.ERROR_CODE_CONFLICT_REQUEST_EXISTING_SCOPE.getCode(), String.format(Oauth2ScopeConstants.ErrorMessages.ERROR_CODE_CONFLICT_REQUEST_EXISTING_SCOPE.getMessage(), scope));
}
}));
}
use of org.wso2.carbon.identity.oauth2.IdentityOAuth2ClientException in project identity-inbound-auth-oauth by wso2-extensions.
the class ScopeClaimMappingDAOImpl method addScope.
/**
* To add OIDC scope for a specific tenant.
*
* @param scope Scope.
* @param tenantId Tenant Id.
* @throws IdentityOAuth2Exception If an error occurs when adding a scope.
*/
@Override
public void addScope(ScopeDTO scope, int tenantId) throws IdentityOAuth2Exception {
// name is exist will throw conflict error.
if (!isScopeExist(scope.getName(), tenantId, true)) {
JdbcTemplate jdbcTemplate = JdbcUtils.getNewTemplate();
try {
int scopeClaimMappingId = jdbcTemplate.executeInsert(SQLQueries.STORE_IDN_OAUTH2_SCOPE, (preparedStatement -> {
preparedStatement.setString(1, scope.getName());
preparedStatement.setString(2, scope.getDisplayName());
preparedStatement.setString(3, scope.getDescription());
preparedStatement.setInt(4, tenantId);
preparedStatement.setString(5, Oauth2ScopeConstants.SCOPE_TYPE_OIDC);
}), null, true, Oauth2ScopeConstants.SCOPE_ID);
if (scopeClaimMappingId > 0 && ArrayUtils.isNotEmpty(scope.getClaim())) {
Set<String> claimsSet = new HashSet<>(Arrays.asList(scope.getClaim()));
insertClaims(tenantId, scopeClaimMappingId, claimsSet);
}
if (log.isDebugEnabled() && ArrayUtils.isNotEmpty(scope.getClaim())) {
log.debug(String.format("The scope %s and the claims %s are successfully inserted for the tenant:" + " %s", scope.getName(), Arrays.asList(scope.getClaim()), tenantId));
}
} catch (DataAccessException e) {
String errorMessage = "Error while persisting scopes for the tenant: " + tenantId;
throw new IdentityOAuth2Exception(errorMessage, e);
}
} else {
log.warn(String.format("Scope %s already exist in tenant %s.", scope.getName(), tenantId));
throw new IdentityOAuth2ClientException(Oauth2ScopeConstants.ErrorMessages.ERROR_CODE_CONFLICT_REQUEST_EXISTING_SCOPE.getCode(), String.format(Oauth2ScopeConstants.ErrorMessages.ERROR_CODE_CONFLICT_REQUEST_EXISTING_SCOPE.getMessage(), scope.getName()));
}
}
use of org.wso2.carbon.identity.oauth2.IdentityOAuth2ClientException in project identity-inbound-auth-oauth by wso2-extensions.
the class OAuth2AuthzEndpointTest method testGetServiceProvider.
@Test(dataProvider = "provideGetServiceProviderData", groups = "testWithConnection")
public void testGetServiceProvider(String clientId, Exception e) throws Exception {
Method getServiceProvider = authzEndpointObject.getClass().getDeclaredMethod("getServiceProvider", String.class);
getServiceProvider.setAccessible(true);
ServiceProvider sp = new ServiceProvider();
sp.setApplicationName(APP_NAME);
mockOAuthServerConfiguration();
mockEndpointUtil(false);
mockApplicationManagementService(sp);
mockStatic(IdentityTenantUtil.class);
when(IdentityTenantUtil.getTenantDomain(anyInt())).thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
when(IdentityTenantUtil.getTenantId(anyString())).thenReturn(MultitenantConstants.SUPER_TENANT_ID);
try (Connection connection = getConnection()) {
mockStatic(IdentityDatabaseUtil.class);
when(IdentityDatabaseUtil.getDBConnection()).thenReturn(connection);
if (e instanceof IdentityOAuth2ClientException) {
when(tokenPersistenceProcessor.getPreprocessedClientSecret(anyString())).thenThrow(e);
}
if (e instanceof IdentityApplicationManagementException) {
ApplicationManagementService appMgtService = mock(ApplicationManagementService.class);
OAuth2ServiceComponentHolder.setApplicationMgtService(appMgtService);
when(appMgtService.getServiceProviderByClientId(anyString(), any(), anyString())).thenThrow(e);
}
try {
ServiceProvider result = (ServiceProvider) getServiceProvider.invoke(authzEndpointObject, clientId);
assertEquals(result.getApplicationName(), APP_NAME);
} catch (Exception e1) {
if (e == null && CLIENT_ID_VALUE.equals(clientId)) {
fail("Unexpected Exception");
}
}
}
}
use of org.wso2.carbon.identity.oauth2.IdentityOAuth2ClientException in project identity-inbound-auth-oauth by wso2-extensions.
the class OAuth2Util method getServiceProvider.
/**
* Returns the service provider associated with the OAuth clientId.
*
* @param clientId OAuth2/OIDC Client Identifier
* @return
* @throws IdentityOAuth2Exception
*/
public static ServiceProvider getServiceProvider(String clientId) throws IdentityOAuth2Exception {
ApplicationManagementService applicationMgtService = OAuth2ServiceComponentHolder.getApplicationMgtService();
String tenantDomain = null;
try {
tenantDomain = getTenantDomainOfOauthApp(clientId);
// Get the Service Provider.
return applicationMgtService.getServiceProviderByClientId(clientId, IdentityApplicationConstants.OAuth2.NAME, tenantDomain);
} catch (IdentityApplicationManagementException e) {
throw new IdentityOAuth2Exception("Error while obtaining the service provider for client_id: " + clientId + " of tenantDomain: " + tenantDomain, e);
} catch (InvalidOAuthClientException e) {
throw new IdentityOAuth2ClientException("Could not find an existing app for clientId: " + clientId, e);
}
}
Aggregations