Search in sources :

Example 1 with AcrChangedException

use of org.gluu.oxauth.model.exception.AcrChangedException in project oxAuth by GluuFederation.

the class AuthorizeRestWebServiceImpl method requestAuthorization.

private Response requestAuthorization(String scope, String responseType, String clientId, String redirectUri, String state, String respMode, String nonce, String display, String prompt, Integer maxAge, String uiLocalesStr, String idTokenHint, String loginHint, String acrValuesStr, String amrValuesStr, String request, String requestUri, String requestSessionId, String sessionId, String method, String originHeaders, String codeChallenge, String codeChallengeMethod, String customRespHeaders, String claims, String authReqId, HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityContext securityContext) {
    // it may be encoded in uma case
    scope = ServerUtil.urlDecode(scope);
    String tokenBindingHeader = httpRequest.getHeader("Sec-Token-Binding");
    OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(httpRequest), Action.USER_AUTHORIZATION);
    oAuth2AuditLog.setClientId(clientId);
    oAuth2AuditLog.setScope(scope);
    // ATTENTION : please do not add more parameter in this debug method because it will not work with Seam 2.2.2.Final ,
    // there is limit of 10 parameters (hardcoded), see: org.jboss.seam.core.Interpolator#interpolate
    log.debug("Attempting to request authorization: " + "responseType = {}, clientId = {}, scope = {}, redirectUri = {}, nonce = {}, " + "state = {}, request = {}, isSecure = {}, requestSessionId = {}, sessionId = {}", responseType, clientId, scope, redirectUri, nonce, state, request, securityContext.isSecure(), requestSessionId, sessionId);
    log.debug("Attempting to request authorization: " + "acrValues = {}, amrValues = {}, originHeaders = {}, codeChallenge = {}, codeChallengeMethod = {}, " + "customRespHeaders = {}, claims = {}, tokenBindingHeader = {}", acrValuesStr, amrValuesStr, originHeaders, codeChallenge, codeChallengeMethod, customRespHeaders, claims, tokenBindingHeader);
    ResponseBuilder builder = Response.ok();
    List<String> uiLocales = Util.splittedStringAsList(uiLocalesStr, " ");
    List<ResponseType> responseTypes = ResponseType.fromString(responseType, " ");
    List<Prompt> prompts = Prompt.fromString(prompt, " ");
    List<String> acrValues = Util.splittedStringAsList(acrValuesStr, " ");
    List<String> amrValues = Util.splittedStringAsList(amrValuesStr, " ");
    ResponseMode responseMode = ResponseMode.getByValue(respMode);
    Map<String, String> customParameters = requestParameterService.getCustomParameters(QueryStringDecoder.decode(httpRequest.getQueryString(), true));
    SessionId sessionUser = identity.getSessionId();
    User user = sessionIdService.getUser(sessionUser);
    try {
        Map<String, String> customResponseHeaders = Util.jsonObjectArrayStringAsMap(customRespHeaders);
        updateSessionForROPC(httpRequest, sessionUser);
        Client client = authorizeRestWebServiceValidator.validateClient(clientId, state);
        String deviceAuthzUserCode = deviceAuthorizationService.getUserCodeFromSession(httpRequest);
        redirectUri = authorizeRestWebServiceValidator.validateRedirectUri(client, redirectUri, state, deviceAuthzUserCode, httpRequest);
        log.trace("Validated URI: {}", redirectUri);
        // check after redirect uri is validated
        checkAcrChanged(acrValuesStr, prompts, sessionUser);
        RedirectUriResponse redirectUriResponse = new RedirectUriResponse(new RedirectUri(redirectUri, responseTypes, responseMode), state, httpRequest, errorResponseFactory);
        redirectUriResponse.setFapiCompatible(appConfiguration.getFapiCompatibility());
        Set<String> scopes = scopeChecker.checkScopesPolicy(client, scope);
        JwtAuthorizationRequest jwtRequest = null;
        if (StringUtils.isNotBlank(request) || StringUtils.isNotBlank(requestUri)) {
            try {
                jwtRequest = JwtAuthorizationRequest.createJwtRequest(request, requestUri, client, redirectUriResponse, cryptoProvider, appConfiguration);
                if (jwtRequest == null) {
                    throw createInvalidJwtRequestException(redirectUriResponse, "Failed to parse jwt.");
                }
                if (StringUtils.isNotBlank(jwtRequest.getState())) {
                    state = jwtRequest.getState();
                    redirectUriResponse.setState(state);
                }
                if (appConfiguration.getFapiCompatibility() && StringUtils.isBlank(jwtRequest.getState())) {
                    // #1250 - FAPI : discard state if in JWT we don't have state
                    state = "";
                    redirectUriResponse.setState("");
                }
                authorizeRestWebServiceValidator.validateRequestObject(jwtRequest, redirectUriResponse);
                // MUST be equal
                if (!jwtRequest.getResponseTypes().containsAll(responseTypes) || !responseTypes.containsAll(jwtRequest.getResponseTypes())) {
                    throw createInvalidJwtRequestException(redirectUriResponse, "The responseType parameter is not the same in the JWT");
                }
                if (StringUtils.isBlank(jwtRequest.getClientId()) || !jwtRequest.getClientId().equals(clientId)) {
                    throw createInvalidJwtRequestException(redirectUriResponse, "The clientId parameter is not the same in the JWT");
                }
                // JWT wins
                if (!jwtRequest.getScopes().isEmpty()) {
                    if (!scopes.contains("openid")) {
                        // spec: Even if a scope parameter is present in the Request Object value, a scope parameter MUST always be passed using the OAuth 2.0 request syntax containing the openid scope value
                        throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_SCOPE, state, "scope parameter does not contain openid value which is required.")).build());
                    }
                    scopes = scopeChecker.checkScopesPolicy(client, Lists.newArrayList(jwtRequest.getScopes()));
                }
                if (jwtRequest.getRedirectUri() != null && !jwtRequest.getRedirectUri().equals(redirectUri)) {
                    throw createInvalidJwtRequestException(redirectUriResponse, "The redirect_uri parameter is not the same in the JWT");
                }
                if (StringUtils.isNotBlank(jwtRequest.getNonce())) {
                    nonce = jwtRequest.getNonce();
                }
                if (jwtRequest.getDisplay() != null && StringUtils.isNotBlank(jwtRequest.getDisplay().getParamName())) {
                    display = jwtRequest.getDisplay().getParamName();
                }
                if (!jwtRequest.getPrompts().isEmpty()) {
                    prompts = Lists.newArrayList(jwtRequest.getPrompts());
                }
                final IdTokenMember idTokenMember = jwtRequest.getIdTokenMember();
                if (idTokenMember != null) {
                    if (idTokenMember.getMaxAge() != null) {
                        maxAge = idTokenMember.getMaxAge();
                    }
                    final Claim acrClaim = idTokenMember.getClaim(JwtClaimName.AUTHENTICATION_CONTEXT_CLASS_REFERENCE);
                    if (acrClaim != null && acrClaim.getClaimValue() != null) {
                        acrValuesStr = acrClaim.getClaimValue().getValueAsString();
                        acrValues = Util.splittedStringAsList(acrValuesStr, " ");
                    }
                    Claim userIdClaim = idTokenMember.getClaim(JwtClaimName.SUBJECT_IDENTIFIER);
                    if (userIdClaim != null && userIdClaim.getClaimValue() != null && userIdClaim.getClaimValue().getValue() != null) {
                        String userIdClaimValue = userIdClaim.getClaimValue().getValue();
                        if (user != null) {
                            String userId = user.getUserId();
                            if (!userId.equalsIgnoreCase(userIdClaimValue)) {
                                builder = redirectUriResponse.createErrorBuilder(AuthorizeErrorResponseType.USER_MISMATCHED);
                                applicationAuditLogger.sendMessage(oAuth2AuditLog);
                                return builder.build();
                            }
                        }
                    }
                }
                requestParameterService.getCustomParameters(jwtRequest, customParameters);
            } catch (WebApplicationException e) {
                throw e;
            } catch (Exception e) {
                log.error("Invalid JWT authorization request. Message : " + e.getMessage(), e);
                throw createInvalidJwtRequestException(redirectUriResponse, "Invalid JWT authorization request");
            }
        }
        if (!cibaRequestService.hasCibaCompatibility(client)) {
            if (appConfiguration.getFapiCompatibility() && jwtRequest == null) {
                throw redirectUriResponse.createWebException(AuthorizeErrorResponseType.INVALID_REQUEST);
            }
            authorizeRestWebServiceValidator.validateRequestJwt(request, requestUri, redirectUriResponse);
        }
        authorizeRestWebServiceValidator.validate(responseTypes, prompts, nonce, state, redirectUri, httpRequest, client, responseMode);
        if (CollectionUtils.isEmpty(acrValues) && !ArrayUtils.isEmpty(client.getDefaultAcrValues())) {
            acrValues = Lists.newArrayList(client.getDefaultAcrValues());
        }
        if (scopes.contains(ScopeConstants.OFFLINE_ACCESS) && !client.getTrustedClient()) {
            if (!responseTypes.contains(ResponseType.CODE)) {
                log.trace("Removed (ignored) offline_scope. Can't find `code` in response_type which is required.");
                scopes.remove(ScopeConstants.OFFLINE_ACCESS);
            }
            if (scopes.contains(ScopeConstants.OFFLINE_ACCESS) && !prompts.contains(Prompt.CONSENT)) {
                log.error("Removed offline_access. Can't find prompt=consent. Consent is required for offline_access.");
                scopes.remove(ScopeConstants.OFFLINE_ACCESS);
            }
        }
        final boolean isResponseTypeValid = AuthorizeParamsValidator.validateResponseTypes(responseTypes, client) && AuthorizeParamsValidator.validateGrantType(responseTypes, client.getGrantTypes(), appConfiguration.getGrantTypesSupported());
        if (!isResponseTypeValid) {
            throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.UNSUPPORTED_RESPONSE_TYPE, state, "")).build());
        }
        AuthorizationGrant authorizationGrant = null;
        if (user == null) {
            identity.logout();
            if (prompts.contains(Prompt.NONE)) {
                if (authenticationFilterService.isEnabled()) {
                    Map<String, String> params;
                    if (method.equals(HttpMethod.GET)) {
                        params = QueryStringDecoder.decode(httpRequest.getQueryString());
                    } else {
                        params = getGenericRequestMap(httpRequest);
                    }
                    String userDn = authenticationFilterService.processAuthenticationFilters(params);
                    if (userDn != null) {
                        Map<String, String> genericRequestMap = getGenericRequestMap(httpRequest);
                        Map<String, String> parameterMap = Maps.newHashMap(genericRequestMap);
                        Map<String, String> requestParameterMap = requestParameterService.getAllowedParameters(parameterMap);
                        sessionUser = sessionIdService.generateAuthenticatedSessionId(httpRequest, userDn, prompt);
                        sessionUser.setSessionAttributes(requestParameterMap);
                        cookieService.createSessionIdCookie(sessionUser, httpRequest, httpResponse, false);
                        sessionIdService.updateSessionId(sessionUser);
                        user = userService.getUserByDn(sessionUser.getUserDn());
                    } else {
                        builder = redirectUriResponse.createErrorBuilder(AuthorizeErrorResponseType.LOGIN_REQUIRED);
                        applicationAuditLogger.sendMessage(oAuth2AuditLog);
                        return builder.build();
                    }
                } else {
                    builder = redirectUriResponse.createErrorBuilder(AuthorizeErrorResponseType.LOGIN_REQUIRED);
                    applicationAuditLogger.sendMessage(oAuth2AuditLog);
                    return builder.build();
                }
            } else {
                if (prompts.contains(Prompt.LOGIN)) {
                    unauthenticateSession(sessionId, httpRequest);
                    sessionId = null;
                    prompts.remove(Prompt.LOGIN);
                }
                return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
            }
        }
        boolean validAuthenticationMaxAge = authorizeRestWebServiceValidator.validateAuthnMaxAge(maxAge, sessionUser, client);
        if (!validAuthenticationMaxAge) {
            unauthenticateSession(sessionId, httpRequest);
            sessionId = null;
            return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        oAuth2AuditLog.setUsername(user.getUserId());
        ExternalPostAuthnContext postAuthnContext = new ExternalPostAuthnContext(client, sessionUser, httpRequest, httpResponse);
        final boolean forceReAuthentication = externalPostAuthnService.externalForceReAuthentication(client, postAuthnContext);
        if (forceReAuthentication) {
            unauthenticateSession(sessionId, httpRequest);
            sessionId = null;
            return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        final boolean forceAuthorization = externalPostAuthnService.externalForceAuthorization(client, postAuthnContext);
        if (forceAuthorization) {
            return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        ClientAuthorization clientAuthorization = null;
        boolean clientAuthorizationFetched = false;
        if (scopes.size() > 0) {
            if (prompts.contains(Prompt.CONSENT)) {
                return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
            }
            if (client.getTrustedClient()) {
                sessionUser.addPermission(clientId, true);
                sessionIdService.updateSessionId(sessionUser);
            } else {
                clientAuthorization = clientAuthorizationsService.find(user.getAttribute("inum"), client.getClientId());
                clientAuthorizationFetched = true;
                if (clientAuthorization != null && clientAuthorization.getScopes() != null) {
                    log.trace("ClientAuthorization - scope: " + scope + ", dn: " + clientAuthorization.getDn() + ", requestedScope: " + scopes);
                    if (Arrays.asList(clientAuthorization.getScopes()).containsAll(scopes)) {
                        sessionUser.addPermission(clientId, true);
                        sessionIdService.updateSessionId(sessionUser);
                    } else {
                        return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
                    }
                }
            }
        }
        if (prompts.contains(Prompt.LOGIN)) {
            // workaround for #1030 - remove only authenticated session, for set up acr we set it unauthenticated and then drop in AuthorizeAction
            if (identity.getSessionId().getState() == SessionIdState.AUTHENTICATED) {
                unauthenticateSession(sessionId, httpRequest);
            }
            sessionId = null;
            prompts.remove(Prompt.LOGIN);
            return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        if (prompts.contains(Prompt.CONSENT) || !sessionUser.isPermissionGrantedForClient(clientId)) {
            if (!clientAuthorizationFetched) {
                clientAuthorization = clientAuthorizationsService.find(user.getAttribute("inum"), client.getClientId());
            }
            clientAuthorizationsService.clearAuthorizations(clientAuthorization, client.getPersistClientAuthorizations());
            prompts.remove(Prompt.CONSENT);
            return redirectToAuthorizationPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        if (prompts.contains(Prompt.SELECT_ACCOUNT)) {
            return redirectToSelectAccountPage(redirectUriResponse.getRedirectUri(), responseTypes, scope, clientId, redirectUri, state, responseMode, nonce, display, prompts, maxAge, uiLocales, idTokenHint, loginHint, acrValues, amrValues, request, requestUri, originHeaders, codeChallenge, codeChallengeMethod, sessionId, claims, authReqId, customParameters, oAuth2AuditLog, httpRequest);
        }
        AuthorizationCode authorizationCode = null;
        if (responseTypes.contains(ResponseType.CODE)) {
            authorizationGrant = authorizationGrantList.createAuthorizationCodeGrant(user, client, sessionUser.getAuthenticationTime());
            authorizationGrant.setNonce(nonce);
            authorizationGrant.setJwtAuthorizationRequest(jwtRequest);
            authorizationGrant.setTokenBindingHash(TokenBindingMessage.getTokenBindingIdHashFromTokenBindingMessage(tokenBindingHeader, client.getIdTokenTokenBindingCnf()));
            authorizationGrant.setScopes(scopes);
            authorizationGrant.setCodeChallenge(codeChallenge);
            authorizationGrant.setCodeChallengeMethod(codeChallengeMethod);
            authorizationGrant.setClaims(claims);
            // Store acr_values
            authorizationGrant.setAcrValues(getAcrForGrant(acrValuesStr, sessionUser));
            authorizationGrant.setSessionDn(sessionUser.getDn());
            // call save after object modification!!!
            authorizationGrant.save();
            authorizationCode = authorizationGrant.getAuthorizationCode();
            redirectUriResponse.getRedirectUri().addResponseParameter("code", authorizationCode.getCode());
        }
        AccessToken newAccessToken = null;
        if (responseTypes.contains(ResponseType.TOKEN)) {
            if (authorizationGrant == null) {
                authorizationGrant = authorizationGrantList.createImplicitGrant(user, client, sessionUser.getAuthenticationTime());
                authorizationGrant.setNonce(nonce);
                authorizationGrant.setJwtAuthorizationRequest(jwtRequest);
                authorizationGrant.setScopes(scopes);
                authorizationGrant.setClaims(claims);
                // Store acr_values
                authorizationGrant.setAcrValues(getAcrForGrant(acrValuesStr, sessionUser));
                authorizationGrant.setSessionDn(sessionUser.getDn());
                // call save after object modification!!!
                authorizationGrant.save();
            }
            newAccessToken = authorizationGrant.createAccessToken(httpRequest.getHeader("X-ClientCert"), new ExecutionContext(httpRequest, httpResponse));
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ACCESS_TOKEN, newAccessToken.getCode());
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.TOKEN_TYPE, newAccessToken.getTokenType().toString());
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.EXPIRES_IN, newAccessToken.getExpiresIn() + "");
        }
        if (responseTypes.contains(ResponseType.ID_TOKEN)) {
            boolean includeIdTokenClaims = Boolean.TRUE.equals(appConfiguration.getLegacyIdTokenClaims());
            if (authorizationGrant == null) {
                includeIdTokenClaims = true;
                authorizationGrant = authorizationGrantList.createImplicitGrant(user, client, sessionUser.getAuthenticationTime());
                authorizationGrant.setNonce(nonce);
                authorizationGrant.setJwtAuthorizationRequest(jwtRequest);
                authorizationGrant.setScopes(scopes);
                authorizationGrant.setClaims(claims);
                // Store authentication acr values
                authorizationGrant.setAcrValues(getAcrForGrant(acrValuesStr, sessionUser));
                authorizationGrant.setSessionDn(sessionUser.getDn());
                // call save after object modification, call is asynchronous!!!
                authorizationGrant.save();
            }
            ExternalUpdateTokenContext context = new ExternalUpdateTokenContext(httpRequest, authorizationGrant, client, appConfiguration, attributeService);
            Function<JsonWebResponse, Void> postProcessor = externalUpdateTokenService.buildModifyIdTokenProcessor(context);
            IdToken idToken = authorizationGrant.createIdToken(nonce, authorizationCode, newAccessToken, null, state, authorizationGrant, includeIdTokenClaims, JwrService.wrapWithSidFunction(TokenBindingMessage.createIdTokenTokingBindingPreprocessing(tokenBindingHeader, client.getIdTokenTokenBindingCnf()), sessionUser.getOutsideSid()), postProcessor);
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ID_TOKEN, idToken.getCode());
        }
        if (authorizationGrant != null && StringHelper.isNotEmpty(acrValuesStr) && !appConfiguration.getFapiCompatibility()) {
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ACR_VALUES, acrValuesStr);
        }
        if (sessionUser.getId() == null) {
            final SessionId newSessionUser = sessionIdService.generateAuthenticatedSessionId(httpRequest, sessionUser.getUserDn(), prompt);
            String newSessionId = newSessionUser.getId();
            sessionUser.setId(newSessionId);
            log.trace("newSessionId = {}", newSessionId);
        }
        if (!appConfiguration.getFapiCompatibility() && appConfiguration.getSessionIdRequestParameterEnabled()) {
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SESSION_ID, sessionUser.getId());
        }
        redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SID, sessionUser.getOutsideSid());
        redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SESSION_STATE, sessionIdService.computeSessionState(sessionUser, clientId, redirectUri));
        redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.STATE, state);
        if (scope != null && !scope.isEmpty() && authorizationGrant != null && !appConfiguration.getFapiCompatibility()) {
            scope = authorizationGrant.checkScopesPolicy(scope);
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SCOPE, scope);
        }
        clientService.updateAccessTime(client, false);
        oAuth2AuditLog.setSuccess(true);
        log.trace("Preparing redirect to: {}", redirectUriResponse.getRedirectUri());
        builder = RedirectUtil.getRedirectResponseBuilder(redirectUriResponse.getRedirectUri(), httpRequest);
        if (appConfiguration.getCustomHeadersWithAuthorizationResponse()) {
            for (String key : customResponseHeaders.keySet()) {
                builder.header(key, customResponseHeaders.get(key));
            }
        }
        if (StringUtils.isNotBlank(authReqId)) {
            runCiba(authReqId, client, httpRequest, httpResponse);
        }
        if (StringUtils.isNotBlank(deviceAuthzUserCode)) {
            processDeviceAuthorization(deviceAuthzUserCode, user);
        }
    } catch (WebApplicationException e) {
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
        log.error(e.getMessage(), e);
        throw e;
    } catch (AcrChangedException e) {
        // Acr changed
        log.error("ACR is changed, please provide a supported and enabled acr value");
        log.error(e.getMessage(), e);
        RedirectUri redirectUriResponse = new RedirectUri(redirectUri, responseTypes, responseMode);
        redirectUriResponse.parseQueryString(errorResponseFactory.getErrorAsQueryString(AuthorizeErrorResponseType.SESSION_SELECTION_REQUIRED, state));
        redirectUriResponse.addResponseParameter("hint", "Use prompt=login in order to alter existing session.");
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
        return RedirectUtil.getRedirectResponseBuilder(redirectUriResponse, httpRequest).build();
    } catch (EntryPersistenceException e) {
        // Invalid clientId
        builder = Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.UNAUTHORIZED_CLIENT, state, "")).type(MediaType.APPLICATION_JSON_TYPE);
        log.error(e.getMessage(), e);
    } catch (InvalidSessionStateException ex) {
        // Allow to handle it via GlobalExceptionHandler
        throw ex;
    } catch (Exception e) {
        // 500
        builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
        log.error(e.getMessage(), e);
    }
    applicationAuditLogger.sendMessage(oAuth2AuditLog);
    return builder.build();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) OAuth2AuditLog(org.gluu.oxauth.model.audit.OAuth2AuditLog) EntryPersistenceException(org.gluu.persist.exception.EntryPersistenceException) RedirectUri(org.gluu.oxauth.util.RedirectUri) InvalidSessionStateException(org.gluu.oxauth.model.exception.InvalidSessionStateException) AcrChangedException(org.gluu.oxauth.model.exception.AcrChangedException) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) Client(org.gluu.oxauth.model.registration.Client) JsonWebResponse(org.gluu.oxauth.model.token.JsonWebResponse) ClientAuthorization(org.gluu.oxauth.model.ldap.ClientAuthorization) ExternalPostAuthnContext(org.gluu.oxauth.service.external.context.ExternalPostAuthnContext) InvalidSessionStateException(org.gluu.oxauth.model.exception.InvalidSessionStateException) EntryPersistenceException(org.gluu.persist.exception.EntryPersistenceException) WebApplicationException(javax.ws.rs.WebApplicationException) AcrChangedException(org.gluu.oxauth.model.exception.AcrChangedException) ExternalUpdateTokenContext(org.gluu.oxauth.service.external.context.ExternalUpdateTokenContext)

Example 2 with AcrChangedException

use of org.gluu.oxauth.model.exception.AcrChangedException in project oxAuth by GluuFederation.

the class AuthorizeAction method checkPermissionGranted.

public void checkPermissionGranted() throws IOException {
    if ((clientId == null) || clientId.isEmpty()) {
        log.debug("Permission denied. client_id should be not empty.");
        permissionDenied();
        return;
    }
    Client client = null;
    try {
        client = clientService.getClient(clientId);
    } catch (EntryPersistenceException ex) {
        log.debug("Permission denied. Failed to find client by inum '{}' in LDAP.", clientId, ex);
        permissionDenied();
        return;
    }
    if (client == null) {
        log.debug("Permission denied. Failed to find client_id '{}' in LDAP.", clientId);
        permissionDenied();
        return;
    }
    // Fix the list of scopes in the authorization page. oxAuth #739
    Set<String> grantedScopes = scopeChecker.checkScopesPolicy(client, scope);
    allowedScope = org.gluu.oxauth.model.util.StringUtils.implode(grantedScopes, " ");
    SessionId session = getSession();
    List<Prompt> prompts = Prompt.fromString(prompt, " ");
    try {
        redirectUri = authorizeRestWebServiceValidator.validateRedirectUri(client, redirectUri, state, session != null ? session.getSessionAttributes().get(SESSION_USER_CODE) : null, (HttpServletRequest) externalContext.getRequest());
    } catch (WebApplicationException e) {
        log.error(e.getMessage(), e);
        permissionDenied();
        return;
    }
    try {
        session = sessionIdService.assertAuthenticatedSessionCorrespondsToNewRequest(session, acrValues);
    } catch (AcrChangedException e) {
        log.debug("There is already existing session which has another acr then {}, session: {}", acrValues, session.getId());
        if (e.isForceReAuthentication()) {
            session = handleAcrChange(session, prompts);
        } else {
            log.error("ACR is changed, please provide a supported and enabled acr value");
            permissionDenied();
            return;
        }
    }
    if (session == null || StringUtils.isBlank(session.getUserDn()) || SessionIdState.AUTHENTICATED != session.getState()) {
        Map<String, String> parameterMap = externalContext.getRequestParameterMap();
        Map<String, String> requestParameterMap = requestParameterService.getAllowedParameters(parameterMap);
        String redirectTo = "/login.xhtml";
        boolean useExternalAuthenticator = externalAuthenticationService.isEnabled(AuthenticationScriptUsageType.INTERACTIVE);
        if (useExternalAuthenticator) {
            List<String> acrValuesList = sessionIdService.acrValuesList(this.acrValues);
            if (acrValuesList.isEmpty()) {
                acrValuesList = Arrays.asList(defaultAuthenticationMode.getName());
            }
            CustomScriptConfiguration customScriptConfiguration = externalAuthenticationService.determineCustomScriptConfiguration(AuthenticationScriptUsageType.INTERACTIVE, acrValuesList);
            if (customScriptConfiguration == null) {
                log.error("Failed to get CustomScriptConfiguration. auth_step: {}, acr_values: {}", 1, this.acrValues);
                permissionDenied();
                return;
            }
            String acr = customScriptConfiguration.getName();
            requestParameterMap.put(JwtClaimName.AUTHENTICATION_CONTEXT_CLASS_REFERENCE, acr);
            requestParameterMap.put("auth_step", Integer.toString(1));
            String tmpRedirectTo = externalAuthenticationService.executeExternalGetPageForStep(customScriptConfiguration, 1);
            if (StringHelper.isNotEmpty(tmpRedirectTo)) {
                log.trace("Redirect to person authentication login page: {}", tmpRedirectTo);
                redirectTo = tmpRedirectTo;
            }
        }
        // Store Remote IP
        requestParameterMap.put(Constants.REMOTE_IP, getRemoteIp());
        // User Code used in Device Authz flow
        if (session != null && session.getSessionAttributes().containsKey(SESSION_USER_CODE)) {
            String userCode = session.getSessionAttributes().get(SESSION_USER_CODE);
            requestParameterMap.put(SESSION_USER_CODE, userCode);
        }
        // Create unauthenticated session
        SessionId unauthenticatedSession = sessionIdService.generateUnauthenticatedSessionId(null, new Date(), SessionIdState.UNAUTHENTICATED, requestParameterMap, false);
        unauthenticatedSession.setSessionAttributes(requestParameterMap);
        unauthenticatedSession.addPermission(clientId, false);
        // Copy ACR script parameters
        if (appConfiguration.getKeepAuthenticatorAttributesOnAcrChange()) {
            authenticationService.copyAuthenticatorExternalAttributes(session, unauthenticatedSession);
        }
        // #1030, fix for flow 4 - transfer previous session permissions to new session
        if (session != null && session.getPermissionGrantedMap() != null && session.getPermissionGrantedMap().getPermissionGranted() != null) {
            for (Map.Entry<String, Boolean> entity : session.getPermissionGrantedMap().getPermissionGranted().entrySet()) {
                unauthenticatedSession.addPermission(entity.getKey(), entity.getValue());
            }
            // #1030, remove previous session
            sessionIdService.remove(session);
        }
        // always persist is prompt is not none
        boolean persisted = sessionIdService.persistSessionId(unauthenticatedSession, !prompts.contains(Prompt.NONE));
        if (persisted && log.isTraceEnabled()) {
            log.trace("Session '{}' persisted to LDAP", unauthenticatedSession.getId());
        }
        this.sessionId = unauthenticatedSession.getId();
        cookieService.createSessionIdCookie(unauthenticatedSession, false);
        cookieService.creatRpOriginIdCookie(redirectUri);
        identity.setSessionId(unauthenticatedSession);
        Map<String, Object> loginParameters = new HashMap<String, Object>();
        if (requestParameterMap.containsKey(AuthorizeRequestParam.LOGIN_HINT)) {
            loginParameters.put(AuthorizeRequestParam.LOGIN_HINT, requestParameterMap.get(AuthorizeRequestParam.LOGIN_HINT));
        }
        boolean enableRedirect = StringHelper.toBoolean(System.getProperty("gluu.enable-redirect", "false"), false);
        if (!enableRedirect && redirectTo.toLowerCase().endsWith("xhtml")) {
            if (redirectTo.toLowerCase().endsWith("postlogin.xhtml")) {
                authenticator.authenticateWithOutcome();
            } else {
                authenticator.prepareAuthenticationForStep(unauthenticatedSession);
                facesService.renderView(redirectTo);
            }
        } else {
            facesService.redirectWithExternal(redirectTo, loginParameters);
        }
        return;
    }
    String userCode = session.getSessionAttributes().get(SESSION_USER_CODE);
    if (StringUtils.isBlank(userCode) && StringUtils.isBlank(redirectionUriService.validateRedirectionUri(clientId, redirectUri))) {
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext.setResponseStatus(HttpServletResponse.SC_BAD_REQUEST);
        externalContext.setResponseContentType(MediaType.APPLICATION_JSON);
        externalContext.getResponseOutputWriter().write(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST_REDIRECT_URI, state, ""));
        facesContext.responseComplete();
    }
    if (log.isTraceEnabled()) {
        log.trace("checkPermissionGranted, userDn = " + session.getUserDn());
    }
    if (prompts.contains(Prompt.SELECT_ACCOUNT)) {
        Map requestParameterMap = requestParameterService.getAllowedParameters(externalContext.getRequestParameterMap());
        facesService.redirect("/selectAccount.xhtml", requestParameterMap);
        return;
    }
    if (prompts.contains(Prompt.NONE) && prompts.size() > 1) {
        invalidRequest();
        return;
    }
    ExternalPostAuthnContext postAuthnContext = new ExternalPostAuthnContext(client, session, (HttpServletRequest) externalContext.getRequest(), (HttpServletResponse) externalContext.getResponse());
    final boolean forceAuthorization = externalPostAuthnService.externalForceAuthorization(client, postAuthnContext);
    final boolean hasConsentPrompt = prompts.contains(Prompt.CONSENT);
    if (!hasConsentPrompt && !forceAuthorization) {
        if (appConfiguration.getTrustedClientEnabled() && client.getTrustedClient()) {
            // if trusted client = true, then skip authorization page and grant access directly
            permissionGranted(session);
            return;
        } else if (ServerUtil.isTrue(appConfiguration.getSkipAuthorizationForOpenIdScopeAndPairwiseId()) && SubjectType.PAIRWISE.toString().equals(client.getSubjectType()) && hasOnlyOpenidScope()) {
            // If a client has only openid scope and pairwise id, person should not have to authorize. oxAuth-743
            permissionGranted(session);
            return;
        }
        final User user = sessionIdService.getUser(session);
        ClientAuthorization clientAuthorization = clientAuthorizationsService.find(user.getAttribute("inum"), client.getClientId());
        if (clientAuthorization != null && clientAuthorization.getScopes() != null && Arrays.asList(clientAuthorization.getScopes()).containsAll(org.gluu.oxauth.model.util.StringUtils.spaceSeparatedToList(scope))) {
            permissionGranted(session);
            return;
        }
    }
    if (externalConsentGatheringService.isEnabled()) {
        if (consentGatherer.isConsentGathered()) {
            log.trace("Consent-gathered flow passed successfully");
            permissionGranted(session);
            return;
        }
        log.trace("Starting external consent-gathering flow");
        boolean result = consentGatherer.configure(session.getUserDn(), clientId, state);
        if (!result) {
            log.error("Failed to initialize external consent-gathering flow.");
            permissionDenied();
            return;
        }
    }
}
Also used : User(org.gluu.oxauth.model.common.User) WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) EntryPersistenceException(org.gluu.persist.exception.EntryPersistenceException) HttpServletRequest(javax.servlet.http.HttpServletRequest) AcrChangedException(org.gluu.oxauth.model.exception.AcrChangedException) ExternalContext(javax.faces.context.ExternalContext) Client(org.gluu.oxauth.model.registration.Client) SessionId(org.gluu.oxauth.model.common.SessionId) ClientAuthorization(org.gluu.oxauth.model.ldap.ClientAuthorization) ExternalPostAuthnContext(org.gluu.oxauth.service.external.context.ExternalPostAuthnContext) Date(java.util.Date) Prompt(org.gluu.oxauth.model.common.Prompt) CustomScriptConfiguration(org.gluu.model.custom.script.conf.CustomScriptConfiguration) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

WebApplicationException (javax.ws.rs.WebApplicationException)2 AcrChangedException (org.gluu.oxauth.model.exception.AcrChangedException)2 ClientAuthorization (org.gluu.oxauth.model.ldap.ClientAuthorization)2 Client (org.gluu.oxauth.model.registration.Client)2 ExternalPostAuthnContext (org.gluu.oxauth.service.external.context.ExternalPostAuthnContext)2 EntryPersistenceException (org.gluu.persist.exception.EntryPersistenceException)2 Date (java.util.Date)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ExternalContext (javax.faces.context.ExternalContext)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)1 CustomScriptConfiguration (org.gluu.model.custom.script.conf.CustomScriptConfiguration)1 OAuth2AuditLog (org.gluu.oxauth.model.audit.OAuth2AuditLog)1 Prompt (org.gluu.oxauth.model.common.Prompt)1 SessionId (org.gluu.oxauth.model.common.SessionId)1 User (org.gluu.oxauth.model.common.User)1 InvalidSessionStateException (org.gluu.oxauth.model.exception.InvalidSessionStateException)1 JsonWebResponse (org.gluu.oxauth.model.token.JsonWebResponse)1 ExternalUpdateTokenContext (org.gluu.oxauth.service.external.context.ExternalUpdateTokenContext)1