Search in sources :

Example 36 with EntryPersistenceException

use of io.jans.orm.exception.EntryPersistenceException in project jans by JanssenProject.

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 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 = {}, sessionId = {}", responseType, clientId, scope, redirectUri, nonce, state, request, securityContext.isSecure(), 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 = null;
    Map<String, String> customParameters = requestParameterService.getCustomParameters(QueryStringDecoder.decode(httpRequest.getQueryString()));
    boolean isPar = Util.isPar(requestUri);
    if (!isPar && isTrue(appConfiguration.getRequirePar())) {
        log.debug("Server configured for PAR only (via requirePar conf property). Failed to find PAR by request_uri (id): {}", requestUri);
        throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST, state, "Failed to find par by request_uri")).type(MediaType.APPLICATION_JSON_TYPE).build());
    }
    if (isPar) {
        final Par par = parService.getParAndValidateForAuthorizationRequest(requestUri, state, clientId);
        // set it to null, we don't want to follow request uri for PAR
        requestUri = null;
        // request is validated and parameters parsed by PAR endpoint before PAR persistence
        request = null;
        log.debug("Setting request parameters from PAR - {}", par);
        responseType = par.getAttributes().getResponseType();
        respMode = par.getAttributes().getResponseMode();
        scope = par.getAttributes().getScope();
        prompt = par.getAttributes().getPrompt();
        redirectUri = par.getAttributes().getRedirectUri();
        acrValuesStr = par.getAttributes().getAcrValuesStr();
        amrValuesStr = par.getAttributes().getAmrValuesStr();
        codeChallenge = par.getAttributes().getCodeChallenge();
        codeChallengeMethod = par.getAttributes().getCodeChallengeMethod();
        if (StringUtils.isNotBlank(par.getAttributes().getState())) {
            state = par.getAttributes().getState();
        } else {
            state = "";
        }
        if (StringUtils.isNotBlank(par.getAttributes().getNonce()))
            nonce = par.getAttributes().getNonce();
        if (StringUtils.isNotBlank(par.getAttributes().getSessionId()))
            sessionId = par.getAttributes().getSessionId();
        if (StringUtils.isNotBlank(par.getAttributes().getCustomResponseHeaders()))
            customRespHeaders = par.getAttributes().getCustomResponseHeaders();
        if (StringUtils.isNotBlank(par.getAttributes().getClaims()))
            claims = par.getAttributes().getClaims();
        if (StringUtils.isNotBlank(par.getAttributes().getOriginHeaders()))
            originHeaders = par.getAttributes().getOriginHeaders();
        if (StringUtils.isNotBlank(par.getAttributes().getUiLocales()))
            uiLocalesStr = par.getAttributes().getUiLocales();
        if (!par.getAttributes().getCustomParameters().isEmpty())
            customParameters.putAll(par.getAttributes().getCustomParameters());
    }
    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);
    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, isPar);
        String deviceAuthzUserCode = deviceAuthorizationService.getUserCodeFromSession(httpRequest);
        redirectUri = authorizeRestWebServiceValidator.validateRedirectUri(client, redirectUri, state, deviceAuthzUserCode, httpRequest);
        // 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.isFapi());
        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 authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "Failed to parse jwt.");
                }
                if (StringUtils.isNotBlank(jwtRequest.getState())) {
                    state = jwtRequest.getState();
                    redirectUriResponse.setState(state);
                }
                if (appConfiguration.isFapi() && StringUtils.isBlank(jwtRequest.getState())) {
                    // #1250 - FAPI : discard state if in JWT we don't have state
                    state = "";
                    redirectUriResponse.setState("");
                }
                if (jwtRequest.getRedirectUri() != null) {
                    redirectUriResponse.getRedirectUri().setBaseRedirectUri(jwtRequest.getRedirectUri());
                }
                // 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 authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "The redirect_uri parameter is not the same in the JWT");
                }
                if (StringUtils.isNotBlank(jwtRequest.getNonce())) {
                    nonce = jwtRequest.getNonce();
                }
                if (StringUtils.isNotBlank(jwtRequest.getCodeChallenge())) {
                    codeChallenge = jwtRequest.getCodeChallenge();
                }
                if (StringUtils.isNotBlank(jwtRequest.getCodeChallengeMethod())) {
                    codeChallengeMethod = jwtRequest.getCodeChallengeMethod();
                }
                if (jwtRequest.getDisplay() != null && StringUtils.isNotBlank(jwtRequest.getDisplay().getParamName())) {
                    display = jwtRequest.getDisplay().getParamName();
                }
                if (!jwtRequest.getPrompts().isEmpty()) {
                    prompts = Lists.newArrayList(jwtRequest.getPrompts());
                }
                if (jwtRequest.getResponseMode() != null) {
                    responseMode = jwtRequest.getResponseMode();
                    redirectUriResponse.getRedirectUri().setResponseMode(responseMode);
                }
                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) {
                JsonWebResponse jwr = parseRequestToJwr(request);
                if (jwr != null) {
                    // to handle Jans Issue#310
                    String checkForAlg = jwr.getClaims().getClaimAsString("alg");
                    if ("none".equals(checkForAlg)) {
                        throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST_OBJECT, "", "The None algorithm in nested JWT is not allowed for FAPI")).type(MediaType.APPLICATION_JSON_TYPE).build());
                    }
                    responseMode = ResponseMode.getByValue(jwr.getClaims().getClaimAsString("response_mode"));
                    if (responseMode == ResponseMode.JWT) {
                        redirectUriResponse.getRedirectUri().setResponseMode(ResponseMode.JWT);
                        fillRedirectUriResponseforJARM(redirectUriResponse, jwr, client);
                        if (appConfiguration.isFapi()) {
                            authorizeRestWebServiceValidator.throwInvalidJwtRequestExceptionAsJwtMode(redirectUriResponse, "Invalid JWT authorization request", jwr.getClaims().getClaimAsString("state"), httpRequest);
                        }
                    }
                }
                throw e;
            } catch (Exception e) {
                log.error("Invalid JWT authorization request. Message : " + e.getMessage(), e);
                throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "Invalid JWT authorization request");
            }
        }
        // JARM
        if (responseMode == ResponseMode.QUERY_JWT || responseMode == ResponseMode.FRAGMENT_JWT || responseMode == ResponseMode.JWT || responseMode == ResponseMode.FORM_POST_JWT) {
            JsonWebResponse jwe = parseRequestToJwr(request);
            fillRedirectUriResponseforJARM(redirectUriResponse, jwe, client);
        }
        // Validate JWT request object after JARM check, because we want to return errors well formatted (JSON/JWT).
        if (jwtRequest != null) {
            validateJwtRequest(clientId, state, httpRequest, responseTypes, redirectUriResponse, jwtRequest);
        }
        if (!cibaRequestService.hasCibaCompatibility(client) && !isPar) {
            if (appConfiguration.isFapi() && jwtRequest == null) {
                throw redirectUriResponse.createWebException(AuthorizeErrorResponseType.INVALID_REQUEST);
            }
            authorizeRestWebServiceValidator.validateRequestJwt(request, requestUri, redirectUriResponse);
        }
        authorizeRestWebServiceValidator.validate(responseTypes, prompts, nonce, state, redirectUri, httpRequest, client, responseMode);
        authorizeRestWebServiceValidator.validatePkce(codeChallenge, redirectUriResponse);
        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);
        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 != null ? 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.isEmpty()) {
            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);
            }
            // There is no need to present the consent page:
            // If Client is a Trusted Client.
            // If a client is configured for pairwise identifiers, and the openid scope is the only scope requested.
            // Also, we should make sure that the claims request is not enabled.
            final boolean isPairwiseWithOnlyOpenIdScope = client.getSubjectType() == SubjectType.PAIRWISE && scopes.size() == 1 && scopes.contains(DefaultScope.OPEN_ID.toString()) && claims == null && (jwtRequest == null || (jwtRequest.getUserInfoMember() == null && jwtRequest.getIdTokenMember() == null));
            if (client.getTrustedClient() || isPairwiseWithOnlyOpenIdScope) {
                sessionUser.addPermission(clientId, true);
                sessionIdService.updateSessionId(sessionUser);
            } else {
                clientAuthorization = clientAuthorizationsService.find(user.getAttribute("inum"), client.getClientId());
                clientAuthorizationFetched = true;
                if (clientAuthorization != null && clientAuthorization.getScopes() != null) {
                    if (log.isTraceEnabled())
                        log.trace("ClientAuthorization - scope: {}, dn: {}, requestedScope: {}", scope, clientAuthorization.getDn(), 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 (identity != null && identity.getSessionId() != null && identity.getSessionId().getState() == SessionIdState.AUTHENTICATED && client != null && Boolean.TRUE.equals(client.getAttributes().getDefaultPromptLogin()) && identity.getSessionId().getAuthenticationTime() != null && new Date().getTime() - identity.getSessionId().getAuthenticationTime().getTime() > 200) {
            prompts.add(Prompt.LOGIN);
        }
        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) || !isTrue(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();
            }
            final ExecutionContext executionContext = new ExecutionContext(httpRequest, httpResponse);
            executionContext.setCertAsPem(httpRequest.getHeader("X-ClientCert"));
            newAccessToken = authorizationGrant.createAccessToken(executionContext);
            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);
            final Function<JsonWebResponse, Void> preProcessor = JwrService.wrapWithSidFunction(TokenBindingMessage.createIdTokenTokingBindingPreprocessing(tokenBindingHeader, client.getIdTokenTokenBindingCnf()), sessionUser.getOutsideSid());
            Function<JsonWebResponse, Void> postProcessor = externalUpdateTokenService.buildModifyIdTokenProcessor(context);
            final ExecutionContext executionContext = context.toExecutionContext();
            executionContext.setPreProcessing(preProcessor);
            executionContext.setPostProcessor(postProcessor);
            executionContext.setIncludeIdTokenClaims(includeIdTokenClaims);
            executionContext.setGrant(authorizationGrant);
            IdToken idToken = authorizationGrant.createIdToken(nonce, authorizationCode, newAccessToken, null, state, executionContext);
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ID_TOKEN, idToken.getCode());
        }
        if (authorizationGrant != null && StringHelper.isNotEmpty(acrValuesStr) && !appConfiguration.isFapi()) {
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ACR_VALUES, acrValuesStr);
        }
        for (Map.Entry<String, String> customParam : requestParameterService.getCustomParameters(customParameters, true).entrySet()) {
            redirectUriResponse.getRedirectUri().addResponseParameter(customParam.getKey(), customParam.getValue());
        }
        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.isFapi() && isTrue(appConfiguration.getSessionIdRequestParameterEnabled())) {
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SESSION_ID, sessionUser.getId());
        }
        if (isTrue(appConfiguration.getIncludeSidInResponse())) {
            // by defalut we do not include sid in response. It should be read by RP from id_token
            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.isFapi()) {
            scope = authorizationGrant.checkScopesPolicy(scope);
            redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.SCOPE, scope);
        }
        clientService.updateAccessTime(client, false);
        oAuth2AuditLog.setSuccess(true);
        builder = RedirectUtil.getRedirectResponseBuilder(redirectUriResponse.getRedirectUri(), httpRequest);
        if (isTrue(appConfiguration.getCustomHeadersWithAuthorizationResponse())) {
            for (Entry<String, String> entry : customResponseHeaders.entrySet()) {
                builder.header(entry.getKey(), entry.getValue());
            }
        }
        if (StringUtils.isNotBlank(authReqId)) {
            runCiba(authReqId, client, httpRequest, httpResponse);
        }
        if (StringUtils.isNotBlank(deviceAuthzUserCode)) {
            processDeviceAuthorization(deviceAuthzUserCode, user);
        }
    } catch (WebApplicationException e) {
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
        if (log.isErrorEnabled())
            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 (InvalidRedirectUrlException e) {
        builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode()).entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST_REDIRECT_URI, 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 : Par(io.jans.as.persistence.model.Par) InvalidRedirectUrlException(io.jans.as.server.model.exception.InvalidRedirectUrlException) User(io.jans.as.common.model.common.User) WebApplicationException(javax.ws.rs.WebApplicationException) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) RedirectUri(io.jans.as.common.util.RedirectUri) InvalidSessionStateException(io.jans.as.server.model.exception.InvalidSessionStateException) AcrChangedException(io.jans.as.server.model.exception.AcrChangedException) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) Client(io.jans.as.common.model.registration.Client) JsonWebResponse(io.jans.as.model.token.JsonWebResponse) ClientAuthorization(io.jans.as.server.model.ldap.ClientAuthorization) ExternalPostAuthnContext(io.jans.as.server.service.external.context.ExternalPostAuthnContext) InvalidSessionStateException(io.jans.as.server.model.exception.InvalidSessionStateException) InvalidJwtException(io.jans.as.model.exception.InvalidJwtException) AcrChangedException(io.jans.as.server.model.exception.AcrChangedException) WebApplicationException(javax.ws.rs.WebApplicationException) InvalidRedirectUrlException(io.jans.as.server.model.exception.InvalidRedirectUrlException) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) AuthorizeErrorResponseType(io.jans.as.model.authorize.AuthorizeErrorResponseType) ExternalUpdateTokenContext(io.jans.as.server.service.external.context.ExternalUpdateTokenContext)

Example 37 with EntryPersistenceException

use of io.jans.orm.exception.EntryPersistenceException in project jans by JanssenProject.

the class UserGroupService method isUserInGroupOrMember.

public boolean isUserInGroupOrMember(String groupDn, String personDn) {
    Filter ownerFilter = Filter.createEqualityFilter("owner", personDn);
    Filter memberFilter = Filter.createEqualityFilter("member", personDn);
    Filter searchFilter = Filter.createORFilter(ownerFilter, memberFilter);
    try {
        return !ldapEntryManager.findEntries(groupDn, UserGroup.class, searchFilter, 1).isEmpty();
    } catch (EntryPersistenceException ex) {
        log.error("Failed to determine if person '{}' memeber or owner of group '{}'", personDn, groupDn, ex);
    }
    return false;
}
Also used : Filter(io.jans.orm.search.filter.Filter) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException)

Example 38 with EntryPersistenceException

use of io.jans.orm.exception.EntryPersistenceException in project jans by JanssenProject.

the class StatService method setupCurrentEntry.

private void setupCurrentEntry(Date now) {
    final String month = periodDateFormat.format(now);
    // jansId=<id>,ou=yyyyMM,ou=stat,o=gluu
    String dn = String.format("jansId=%s,%s", nodeId, monthlyDn);
    if (currentEntry != null && month.equals(currentEntry.getStat().getMonth())) {
        return;
    }
    try {
        StatEntry entryFromPersistence = entryManager.find(StatEntry.class, dn);
        if (entryFromPersistence != null && month.equals(entryFromPersistence.getStat().getMonth())) {
            hll = HLL.fromBytes(Base64.getDecoder().decode(entryFromPersistence.getUserHllData()));
            tokenCounters = new ConcurrentHashMap<>(entryFromPersistence.getStat().getTokenCountPerGrantType());
            currentEntry = entryFromPersistence;
            log.trace("Stat entry loaded.");
            return;
        }
    } catch (EntryPersistenceException e) {
        log.trace("Stat entry is not found in persistence.");
    }
    if (currentEntry == null) {
        log.trace("Creating stat entry ...");
        hll = newHll();
        tokenCounters = new ConcurrentHashMap<>();
        currentEntry = new StatEntry();
        currentEntry.setId(nodeId);
        currentEntry.setDn(dn);
        currentEntry.setUserHllData(Base64.getEncoder().encodeToString(hll.toBytes()));
        currentEntry.getStat().setMonth(periodDateFormat.format(new Date()));
        entryManager.persist(currentEntry);
        log.trace("Created stat entry.");
    }
}
Also used : StatEntry(io.jans.as.common.model.stat.StatEntry) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) Date(java.util.Date)

Example 39 with EntryPersistenceException

use of io.jans.orm.exception.EntryPersistenceException in project jans by JanssenProject.

the class UserInfoRestWebServiceImpl method requestUserInfo.

private Response requestUserInfo(String accessToken, String authorization, HttpServletRequest request, SecurityContext securityContext) {
    if (tokenService.isBearerAuthToken(authorization)) {
        accessToken = tokenService.getBearerToken(authorization);
    }
    log.debug("Attempting to request User Info, Access token = {}, Is Secure = {}", accessToken, securityContext.isSecure());
    errorResponseFactory.validateComponentEnabled(ComponentType.USERINFO);
    Response.ResponseBuilder builder = Response.ok();
    OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(request), Action.USER_INFO);
    try {
        if (!UserInfoParamsValidator.validateParams(accessToken)) {
            return response(400, UserInfoErrorResponseType.INVALID_REQUEST, "access token is not valid.");
        }
        AuthorizationGrant authorizationGrant = authorizationGrantList.getAuthorizationGrantByAccessToken(accessToken);
        if (authorizationGrant == null) {
            log.trace("Failed to find authorization grant by access_token: {}", accessToken);
            return response(401, UserInfoErrorResponseType.INVALID_TOKEN);
        }
        oAuth2AuditLog.updateOAuth2AuditLog(authorizationGrant, false);
        final AbstractToken accessTokenObject = authorizationGrant.getAccessToken(accessToken);
        if (accessTokenObject == null || !accessTokenObject.isValid()) {
            log.trace("Invalid access token object, access_token: {}, isNull: {}, isValid: {}", accessToken, accessTokenObject == null, false);
            return response(401, UserInfoErrorResponseType.INVALID_TOKEN);
        }
        if (authorizationGrant.getAuthorizationGrantType() == AuthorizationGrantType.CLIENT_CREDENTIALS) {
            return response(403, UserInfoErrorResponseType.INSUFFICIENT_SCOPE, "Grant object has client_credentials grant_type which is not valid.");
        }
        if (appConfiguration.getOpenidScopeBackwardCompatibility() && !authorizationGrant.getScopes().contains(DefaultScope.OPEN_ID.toString()) && !authorizationGrant.getScopes().contains(DefaultScope.PROFILE.toString())) {
            return response(403, UserInfoErrorResponseType.INSUFFICIENT_SCOPE, "Both openid and profile scopes are not present.");
        }
        if (!appConfiguration.getOpenidScopeBackwardCompatibility() && !authorizationGrant.getScopes().contains(DefaultScope.OPEN_ID.toString())) {
            return response(403, UserInfoErrorResponseType.INSUFFICIENT_SCOPE, "Missed openid scope.");
        }
        oAuth2AuditLog.updateOAuth2AuditLog(authorizationGrant, true);
        builder.cacheControl(ServerUtil.cacheControlWithNoStoreTransformAndPrivate());
        builder.header(Constants.PRAGMA, Constants.NO_CACHE);
        User currentUser = authorizationGrant.getUser();
        try {
            currentUser = userService.getUserByDn(authorizationGrant.getUserDn());
        } catch (EntryPersistenceException ex) {
            log.warn("Failed to reload user entry: '{}'", authorizationGrant.getUserDn());
        }
        if (authorizationGrant.getClient() != null && authorizationGrant.getClient().getUserInfoEncryptedResponseAlg() != null && authorizationGrant.getClient().getUserInfoEncryptedResponseEnc() != null) {
            KeyEncryptionAlgorithm keyEncryptionAlgorithm = KeyEncryptionAlgorithm.fromName(authorizationGrant.getClient().getUserInfoEncryptedResponseAlg());
            BlockEncryptionAlgorithm blockEncryptionAlgorithm = BlockEncryptionAlgorithm.fromName(authorizationGrant.getClient().getUserInfoEncryptedResponseEnc());
            builder.type("application/jwt");
            builder.entity(getJweResponse(keyEncryptionAlgorithm, blockEncryptionAlgorithm, currentUser, authorizationGrant, authorizationGrant.getScopes()));
        } else if (authorizationGrant.getClient() != null && authorizationGrant.getClient().getUserInfoSignedResponseAlg() != null) {
            SignatureAlgorithm algorithm = SignatureAlgorithm.fromString(authorizationGrant.getClient().getUserInfoSignedResponseAlg());
            builder.type("application/jwt");
            builder.entity(getJwtResponse(algorithm, currentUser, authorizationGrant, authorizationGrant.getScopes()));
        } else {
            builder.type((MediaType.APPLICATION_JSON + ";charset=UTF-8"));
            builder.entity(getJSonResponse(currentUser, authorizationGrant, authorizationGrant.getScopes()));
        }
        return builder.build();
    } catch (Exception e) {
        log.error(e.getMessage(), e);
        // 500
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
    } finally {
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
    }
}
Also used : JsonWebResponse(io.jans.as.model.token.JsonWebResponse) Response(javax.ws.rs.core.Response) User(io.jans.as.common.model.common.User) AbstractToken(io.jans.as.server.model.common.AbstractToken) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog) KeyEncryptionAlgorithm(io.jans.as.model.crypto.encryption.KeyEncryptionAlgorithm) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) SignatureAlgorithm(io.jans.as.model.crypto.signature.SignatureAlgorithm) UnmodifiableAuthorizationGrant(io.jans.as.server.model.common.UnmodifiableAuthorizationGrant) AuthorizationGrant(io.jans.as.server.model.common.AuthorizationGrant) InvalidClaimException(io.jans.as.model.exception.InvalidClaimException) ParseException(java.text.ParseException) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) InvalidJweException(io.jans.as.model.exception.InvalidJweException) BlockEncryptionAlgorithm(io.jans.as.model.crypto.encryption.BlockEncryptionAlgorithm)

Example 40 with EntryPersistenceException

use of io.jans.orm.exception.EntryPersistenceException in project jans by JanssenProject.

the class UmaValidationService method validatePermission.

public void validatePermission(io.jans.as.model.uma.UmaPermission permission, Client client) {
    String resourceId = permission.getResourceId();
    if (StringHelper.isEmpty(resourceId)) {
        log.error("Resource id is empty");
        throw errorResponseFactory.createWebApplicationException(BAD_REQUEST, INVALID_RESOURCE_ID, "Resource id is empty");
    }
    try {
        UmaResource resource = resourceService.getResourceById(resourceId);
        if (resource == null) {
            log.error("Resource isn't registered or there are two resources with same Id");
            throw errorResponseFactory.createWebApplicationException(BAD_REQUEST, INVALID_RESOURCE_ID, "Resource is not registered.");
        }
        for (String s : permission.getScopes()) {
            if (resource.getScopes().contains(s)) {
                continue;
            }
            final Scope spontaneousScope = umaScopeService.getOrCreate(client, s, Sets.newHashSet(umaScopeService.getScopeIdsByDns(resource.getScopes())));
            if (spontaneousScope == null) {
                log.error("Scope isn't registered and is not allowed by spontaneous scopes. Scope: {}", s);
                throw errorResponseFactory.createWebApplicationException(BAD_REQUEST, INVALID_SCOPE, "At least one of the scopes isn't registered");
            }
        }
        return;
    } catch (EntryPersistenceException ex) {
        log.error(ex.getMessage(), ex);
    }
    log.error("Resource isn't registered");
    throw errorResponseFactory.createWebApplicationException(BAD_REQUEST, INVALID_RESOURCE_ID, "Resource isn't registered");
}
Also used : Scope(io.jans.as.persistence.model.Scope) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) UmaResource(io.jans.as.model.uma.persistence.UmaResource)

Aggregations

EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)61 SearchException (io.jans.orm.exception.operation.SearchException)33 AuthenticationException (io.jans.orm.exception.AuthenticationException)31 EntryDeleteException (io.jans.orm.exception.EntryDeleteException)30 MappingException (io.jans.orm.exception.MappingException)30 Filter (io.jans.orm.search.filter.Filter)24 AttributeData (io.jans.orm.model.AttributeData)16 DateTimeParseException (java.time.format.DateTimeParseException)15 PropertyAnnotation (io.jans.orm.reflect.property.PropertyAnnotation)13 ParsedKey (io.jans.orm.impl.model.ParsedKey)12 ArrayList (java.util.ArrayList)11 Date (java.util.Date)10 SearchScopeException (io.jans.orm.exception.operation.SearchScopeException)9 JsonObject (com.couchbase.client.java.document.json.JsonObject)8 ConnectionException (io.jans.orm.exception.operation.ConnectionException)8 ParseException (java.text.ParseException)8 DateTimeException (java.time.DateTimeException)7 List (java.util.List)7 SearchResultEntry (com.unboundid.ldap.sdk.SearchResultEntry)6 EntryData (io.jans.orm.model.EntryData)6