Search in sources :

Example 1 with OAuth2AuditLog

use of io.jans.as.server.model.audit.OAuth2AuditLog in project jans by JanssenProject.

the class DeviceAuthorizationRestWebServiceImpl method deviceAuthorization.

@Override
public Response deviceAuthorization(String clientId, String scope, HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityContext securityContext) {
    // it may be encoded
    scope = ServerUtil.urlDecode(scope);
    OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(httpRequest), Action.DEVICE_CODE_AUTHORIZATION);
    oAuth2AuditLog.setClientId(clientId);
    oAuth2AuditLog.setScope(scope);
    try {
        log.debug("Attempting to request device codes: clientId = {}, scope = {}", clientId, scope);
        errorResponseFactory.validateComponentEnabled(ComponentType.DEVICE_AUTHZ);
        SessionClient sessionClient = identity.getSessionClient();
        Client client = sessionClient != null ? sessionClient.getClient() : null;
        if (client == null) {
            client = clientService.getClient(clientId);
            if (!clientService.isPublic(client)) {
                log.trace("Client is not public and not authenticated. Skip device authorization, clientId: {}", clientId);
                throw errorResponseFactory.createWebApplicationException(Response.Status.UNAUTHORIZED, INVALID_CLIENT, "");
            }
        }
        if (client == null) {
            log.trace("Client is not unknown. Skip revoking.");
            throw errorResponseFactory.createWebApplicationException(Response.Status.UNAUTHORIZED, INVALID_CLIENT, "");
        }
        if (!deviceAuthorizationService.hasDeviceCodeCompatibility(client)) {
            throw errorResponseFactory.createWebApplicationException(Response.Status.BAD_REQUEST, INVALID_GRANT, "");
        }
        List<String> scopes = new ArrayList<>();
        if (StringHelper.isNotEmpty(scope)) {
            Set<String> grantedScopes = scopeChecker.checkScopesPolicy(client, scope);
            scopes.addAll(grantedScopes);
        }
        // Entropy 20^8 which is suggested in the RFC8628 section 6.1
        String userCode = StringUtils.generateRandomReadableCode((byte) 8);
        // Entropy 160 bits which is over userCode entropy based on RFC8628 section 5.2
        String deviceCode = StringUtils.generateRandomCode((byte) 24);
        URI verificationUri = UriBuilder.fromUri(appConfiguration.getIssuer()).path("device-code").build();
        int expiresIn = appConfiguration.getDeviceAuthzRequestExpiresIn();
        int interval = appConfiguration.getDeviceAuthzTokenPollInterval();
        long lastAccess = System.currentTimeMillis();
        DeviceAuthorizationStatus status = DeviceAuthorizationStatus.PENDING;
        DeviceAuthorizationCacheControl deviceAuthorizationCacheControl = new DeviceAuthorizationCacheControl(userCode, deviceCode, client, scopes, verificationUri, expiresIn, interval, lastAccess, status);
        deviceAuthorizationService.saveInCache(deviceAuthorizationCacheControl, true, true);
        log.info("Device authorization flow initiated, userCode: {}, deviceCode: {}, clientId: {}, verificationUri: {}, expiresIn: {}, interval: {}", userCode, deviceCode, clientId, verificationUri, expiresIn, interval);
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
        return Response.ok().entity(getResponseJSONObject(deviceAuthorizationCacheControl).toString(4).replace("\\/", "/")).type(MediaType.APPLICATION_JSON_TYPE).build();
    } catch (WebApplicationException wae) {
        throw wae;
    } catch (Exception e) {
        log.error("Problems processing device authorization init flow, clientId: {}, scope: {}", clientId, scope, e);
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }
}
Also used : DeviceAuthorizationCacheControl(io.jans.as.server.model.common.DeviceAuthorizationCacheControl) WebApplicationException(javax.ws.rs.WebApplicationException) SessionClient(io.jans.as.server.model.session.SessionClient) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog) ArrayList(java.util.ArrayList) URI(java.net.URI) VERIFICATION_URI(io.jans.as.model.authorize.DeviceAuthorizationResponseParam.VERIFICATION_URI) JSONException(org.json.JSONException) WebApplicationException(javax.ws.rs.WebApplicationException) DeviceAuthorizationStatus(io.jans.as.server.model.common.DeviceAuthorizationStatus) Client(io.jans.as.common.model.registration.Client) SessionClient(io.jans.as.server.model.session.SessionClient)

Example 2 with OAuth2AuditLog

use of io.jans.as.server.model.audit.OAuth2AuditLog in project jans by JanssenProject.

the class BackchannelAuthorizeRestWebServiceImpl method requestBackchannelAuthorizationPost.

@Override
public Response requestBackchannelAuthorizationPost(String clientId, String scope, String clientNotificationToken, String acrValues, String loginHintToken, String idTokenHint, String loginHint, String bindingMessage, String userCodeParam, Integer requestedExpiry, String request, String requestUri, HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityContext securityContext) {
    // it may be encoded
    scope = ServerUtil.urlDecode(scope);
    OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(httpRequest), Action.BACKCHANNEL_AUTHENTICATION);
    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 backchannel authorization: " + "clientId = {}, scope = {}, clientNotificationToken = {}, acrValues = {}, loginHintToken = {}, " + "idTokenHint = {}, loginHint = {}, bindingMessage = {}, userCodeParam = {}, requestedExpiry = {}, " + "request= {}", clientId, scope, clientNotificationToken, acrValues, loginHintToken, idTokenHint, loginHint, bindingMessage, userCodeParam, requestedExpiry, request);
    log.debug("Attempting to request backchannel authorization: " + "isSecure = {}", securityContext.isSecure());
    errorResponseFactory.validateComponentEnabled(ComponentType.CIBA);
    Response.ResponseBuilder builder = Response.ok();
    SessionClient sessionClient = identity.getSessionClient();
    Client client = null;
    if (sessionClient != null) {
        client = sessionClient.getClient();
    }
    if (client == null) {
        // 401
        builder = Response.status(Response.Status.UNAUTHORIZED.getStatusCode());
        builder.entity(errorResponseFactory.getErrorAsJson(INVALID_CLIENT));
        return builder.build();
    }
    if (!cibaRequestService.hasCibaCompatibility(client)) {
        // 401
        builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
        builder.entity(errorResponseFactory.getErrorAsJson(INVALID_REQUEST));
        return builder.build();
    }
    List<String> scopes = new ArrayList<>();
    if (StringHelper.isNotEmpty(scope)) {
        Set<String> grantedScopes = scopeChecker.checkScopesPolicy(client, scope);
        scopes.addAll(grantedScopes);
    }
    JwtAuthorizationRequest jwtRequest = null;
    if (StringUtils.isNotBlank(request) || StringUtils.isNotBlank(requestUri)) {
        jwtRequest = JwtAuthorizationRequest.createJwtRequest(request, requestUri, client, null, cryptoProvider, appConfiguration);
        if (jwtRequest == null) {
            log.error("The JWT couldn't be processed");
            // 400
            builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
            builder.entity(errorResponseFactory.getErrorAsJson(INVALID_REQUEST));
            throw new WebApplicationException(builder.build());
        }
        authorizeRestWebServiceValidator.validateCibaRequestObject(jwtRequest, client.getClientId());
        // JWT wins
        if (!jwtRequest.getScopes().isEmpty()) {
            scopes.addAll(scopeChecker.checkScopesPolicy(client, jwtRequest.getScopes()));
        }
        if (StringUtils.isNotBlank(jwtRequest.getClientNotificationToken())) {
            clientNotificationToken = jwtRequest.getClientNotificationToken();
        }
        if (StringUtils.isNotBlank(jwtRequest.getAcrValues())) {
            acrValues = jwtRequest.getAcrValues();
        }
        if (StringUtils.isNotBlank(jwtRequest.getLoginHintToken())) {
            loginHintToken = jwtRequest.getLoginHintToken();
        }
        if (StringUtils.isNotBlank(jwtRequest.getIdTokenHint())) {
            idTokenHint = jwtRequest.getIdTokenHint();
        }
        if (StringUtils.isNotBlank(jwtRequest.getLoginHint())) {
            loginHint = jwtRequest.getLoginHint();
        }
        if (StringUtils.isNotBlank(jwtRequest.getBindingMessage())) {
            bindingMessage = jwtRequest.getBindingMessage();
        }
        if (StringUtils.isNotBlank(jwtRequest.getUserCode())) {
            userCodeParam = jwtRequest.getUserCode();
        }
        if (jwtRequest.getRequestedExpiry() != null) {
            requestedExpiry = jwtRequest.getRequestedExpiry();
        } else if (jwtRequest.getExp() != null) {
            requestedExpiry = Math.toIntExact(jwtRequest.getExp() - System.currentTimeMillis() / 1000);
        }
    }
    if (appConfiguration.isFapi() && jwtRequest == null) {
        // 400
        builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
        builder.entity(errorResponseFactory.getErrorAsJson(INVALID_REQUEST));
        return builder.build();
    }
    User user = null;
    try {
        if (Strings.isNotBlank(loginHint)) {
            // login_hint
            user = userService.getUniqueUserByAttributes(appConfiguration.getBackchannelLoginHintClaims(), loginHint);
        } else if (Strings.isNotBlank(idTokenHint)) {
            // id_token_hint
            AuthorizationGrant authorizationGrant = authorizationGrantList.getAuthorizationGrantByIdToken(idTokenHint);
            if (authorizationGrant == null) {
                // 400
                builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
                builder.entity(errorResponseFactory.getErrorAsJson(UNKNOWN_USER_ID));
                return builder.build();
            }
            user = authorizationGrant.getUser();
        }
        if (Strings.isNotBlank(loginHintToken)) {
            // login_hint_token
            Jwt jwt = Jwt.parse(loginHintToken);
            SignatureAlgorithm algorithm = jwt.getHeader().getSignatureAlgorithm();
            String keyId = jwt.getHeader().getKeyId();
            if (algorithm == null || Strings.isBlank(keyId)) {
                // 400
                builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
                builder.entity(errorResponseFactory.getErrorAsJson(UNKNOWN_USER_ID));
                return builder.build();
            }
            boolean validSignature = false;
            if (algorithm.getFamily() == AlgorithmFamily.RSA) {
                RSAPublicKey publicKey = JwkClient.getRSAPublicKey(client.getJwksUri(), keyId);
                RSASigner rsaSigner = new RSASigner(algorithm, publicKey);
                validSignature = rsaSigner.validate(jwt);
            } else if (algorithm.getFamily() == AlgorithmFamily.EC) {
                ECDSAPublicKey publicKey = JwkClient.getECDSAPublicKey(client.getJwksUri(), keyId);
                ECDSASigner ecdsaSigner = new ECDSASigner(algorithm, publicKey);
                validSignature = ecdsaSigner.validate(jwt);
            }
            if (!validSignature) {
                // 400
                builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
                builder.entity(errorResponseFactory.getErrorAsJson(UNKNOWN_USER_ID));
                return builder.build();
            }
            JSONObject subject = jwt.getClaims().getClaimAsJSON("subject");
            if (subject == null || !subject.has("subject_type") || !subject.has(subject.getString("subject_type"))) {
                // 400
                builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
                builder.entity(errorResponseFactory.getErrorAsJson(UNKNOWN_USER_ID));
                return builder.build();
            }
            String subjectTypeKey = subject.getString("subject_type");
            String subjectTypeValue = subject.getString(subjectTypeKey);
            user = userService.getUniqueUserByAttributes(appConfiguration.getBackchannelLoginHintClaims(), subjectTypeValue);
        }
    } catch (InvalidJwtException e) {
        log.error(e.getMessage(), e);
    } catch (JSONException e) {
        log.error(e.getMessage(), e);
    }
    if (user == null) {
        // 400
        builder = Response.status(Response.Status.BAD_REQUEST.getStatusCode());
        builder.entity(errorResponseFactory.getErrorAsJson(UNKNOWN_USER_ID));
        return builder.build();
    }
    try {
        String userCode = (String) user.getAttribute("jansBackchannelUsrCode", true, false);
        DefaultErrorResponse cibaAuthorizeParamsValidation = cibaAuthorizeParamsValidatorService.validateParams(scopes, clientNotificationToken, client.getBackchannelTokenDeliveryMode(), loginHintToken, idTokenHint, loginHint, bindingMessage, client.getBackchannelUserCodeParameter(), userCodeParam, userCode, requestedExpiry);
        if (cibaAuthorizeParamsValidation != null) {
            builder = Response.status(cibaAuthorizeParamsValidation.getStatus());
            builder.entity(errorResponseFactory.errorAsJson(cibaAuthorizeParamsValidation.getType(), cibaAuthorizeParamsValidation.getReason()));
            return builder.build();
        }
        String deviceRegistrationToken = (String) user.getAttribute("jansBackchannelDeviceRegistrationTkn", true, false);
        if (deviceRegistrationToken == null) {
            // 401
            builder = Response.status(Response.Status.UNAUTHORIZED.getStatusCode());
            builder.entity(errorResponseFactory.getErrorAsJson(UNAUTHORIZED_END_USER_DEVICE));
            return builder.build();
        }
        int expiresIn = requestedExpiry != null ? requestedExpiry : appConfiguration.getBackchannelAuthenticationResponseExpiresIn();
        Integer interval = client.getBackchannelTokenDeliveryMode() == BackchannelTokenDeliveryMode.PUSH ? null : appConfiguration.getBackchannelAuthenticationResponseInterval();
        long currentTime = new Date().getTime();
        CibaRequestCacheControl cibaRequestCacheControl = new CibaRequestCacheControl(user, client, expiresIn, scopes, clientNotificationToken, bindingMessage, currentTime, acrValues);
        cibaRequestService.save(cibaRequestCacheControl, expiresIn);
        String authReqId = cibaRequestCacheControl.getAuthReqId();
        // Notify End-User to obtain Consent/Authorization
        cibaEndUserNotificationService.notifyEndUser(cibaRequestCacheControl.getScopesAsString(), cibaRequestCacheControl.getAcrValues(), authReqId, deviceRegistrationToken);
        builder.entity(getJSONObject(authReqId, expiresIn, interval).toString(4).replace("\\/", "/"));
        builder.type(MediaType.APPLICATION_JSON_TYPE);
        builder.cacheControl(ServerUtil.cacheControl(true, false));
    } catch (JSONException e) {
        builder = Response.status(400);
        builder.entity(errorResponseFactory.getErrorAsJson(INVALID_REQUEST));
        log.error(e.getMessage(), e);
    } catch (InvalidClaimException e) {
        builder = Response.status(400);
        builder.entity(errorResponseFactory.getErrorAsJson(INVALID_REQUEST));
        log.error(e.getMessage(), e);
    }
    applicationAuditLogger.sendMessage(oAuth2AuditLog);
    return builder.build();
}
Also used : InvalidJwtException(io.jans.as.model.exception.InvalidJwtException) User(io.jans.as.common.model.common.User) WebApplicationException(javax.ws.rs.WebApplicationException) SessionClient(io.jans.as.server.model.session.SessionClient) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog) ArrayList(java.util.ArrayList) CibaRequestCacheControl(io.jans.as.server.model.common.CibaRequestCacheControl) SignatureAlgorithm(io.jans.as.model.crypto.signature.SignatureAlgorithm) InvalidClaimException(io.jans.as.model.exception.InvalidClaimException) RSAPublicKey(io.jans.as.model.crypto.signature.RSAPublicKey) RSASigner(io.jans.as.model.jws.RSASigner) JwtAuthorizationRequest(io.jans.as.server.model.authorize.JwtAuthorizationRequest) JwkClient(io.jans.as.client.JwkClient) Client(io.jans.as.common.model.registration.Client) SessionClient(io.jans.as.server.model.session.SessionClient) DefaultErrorResponse(io.jans.as.model.error.DefaultErrorResponse) AuthorizationGrant(io.jans.as.server.model.common.AuthorizationGrant) ECDSAPublicKey(io.jans.as.model.crypto.signature.ECDSAPublicKey) ECDSASigner(io.jans.as.model.jws.ECDSASigner) Jwt(io.jans.as.model.jwt.Jwt) JSONException(org.json.JSONException) Date(java.util.Date) Response(javax.ws.rs.core.Response) DefaultErrorResponse(io.jans.as.model.error.DefaultErrorResponse) HttpServletResponse(javax.servlet.http.HttpServletResponse) JSONObject(org.json.JSONObject)

Example 3 with OAuth2AuditLog

use of io.jans.as.server.model.audit.OAuth2AuditLog in project jans by JanssenProject.

the class SessionIdService method auditLogging.

private void auditLogging(SessionId sessionId) {
    HttpServletRequest httpServletRequest = ServerUtil.getRequestOrNull();
    if (httpServletRequest != null) {
        Action action;
        switch(sessionId.getState()) {
            case AUTHENTICATED:
                action = Action.SESSION_AUTHENTICATED;
                break;
            case UNAUTHENTICATED:
                action = Action.SESSION_UNAUTHENTICATED;
                break;
            default:
                action = Action.SESSION_UNAUTHENTICATED;
        }
        OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(httpServletRequest), action);
        oAuth2AuditLog.setSuccess(true);
        applicationAuditLogger.sendMessage(oAuth2AuditLog);
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) Action(io.jans.as.server.model.audit.Action) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog)

Example 4 with OAuth2AuditLog

use of io.jans.as.server.model.audit.OAuth2AuditLog in project jans by JanssenProject.

the class RegisterRestWebServiceImpl method requestClientRead.

@Override
public Response requestClientRead(String clientId, String authorization, HttpServletRequest httpRequest, SecurityContext securityContext) {
    String accessToken = tokenService.getToken(authorization);
    log.debug("Attempting to read client: clientId = {}, registrationAccessToken = {} isSecure = {}", clientId, accessToken, securityContext.isSecure());
    errorResponseFactory.validateComponentEnabled(ComponentType.REGISTRATION);
    Response.ResponseBuilder builder = Response.ok();
    OAuth2AuditLog oAuth2AuditLog = new OAuth2AuditLog(ServerUtil.getIpAddress(httpRequest), Action.CLIENT_READ);
    oAuth2AuditLog.setClientId(clientId);
    try {
        if (registerParamsValidator.validateParamsClientRead(clientId, accessToken)) {
            if (isTrue(appConfiguration.getDcrAuthorizationWithClientCredentials())) {
                validateAuthorizationAccessToken(accessToken, clientId);
            }
            Client client = clientService.getClient(clientId, accessToken);
            if (client != null) {
                oAuth2AuditLog.setScope(clientScopesToString(client));
                oAuth2AuditLog.setSuccess(true);
                JSONObject jsonObject = getJSONObject(client);
                jsonObject = modifyReadScript(jsonObject, new ExecutionContext(httpRequest, null).setClient(client));
                builder.entity(jsonObjectToString(jsonObject));
            } else {
                log.trace("The Access Token is not valid for the Client ID, returns invalid_token error.");
                builder = Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).type(MediaType.APPLICATION_JSON_TYPE);
                builder.entity(errorResponseFactory.errorAsJson(RegisterErrorResponseType.INVALID_TOKEN, "The Access Token is not valid for the Client"));
            }
        } else {
            log.trace("Client ID or Access Token is not valid.");
            throw errorResponseFactory.createWebApplicationException(Response.Status.BAD_REQUEST, RegisterErrorResponseType.INVALID_CLIENT_METADATA, "Client ID or Access Token is not valid.");
        }
    } catch (JSONException e) {
        log.error(e.getMessage(), e);
        throw errorResponseFactory.createWebApplicationException(Response.Status.INTERNAL_SERVER_ERROR, RegisterErrorResponseType.INVALID_CLIENT_METADATA, "Failed to parse json.");
    } catch (StringEncrypter.EncryptionException e) {
        log.error(e.getMessage(), e);
        throw errorResponseFactory.createWebApplicationException(Response.Status.INTERNAL_SERVER_ERROR, RegisterErrorResponseType.INVALID_CLIENT_METADATA, "Encryption exception occurred.");
    }
    builder.cacheControl(ServerUtil.cacheControl(true, false));
    builder.header(Constants.PRAGMA, Constants.NO_CACHE);
    applicationAuditLogger.sendMessage(oAuth2AuditLog);
    return builder.build();
}
Also used : Response(javax.ws.rs.core.Response) ExecutionContext(io.jans.as.server.model.common.ExecutionContext) JSONObject(org.json.JSONObject) OAuth2AuditLog(io.jans.as.server.model.audit.OAuth2AuditLog) JSONException(org.json.JSONException) Client(io.jans.as.common.model.registration.Client) StringEncrypter(io.jans.util.security.StringEncrypter)

Example 5 with OAuth2AuditLog

use of io.jans.as.server.model.audit.OAuth2AuditLog 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)

Aggregations

OAuth2AuditLog (io.jans.as.server.model.audit.OAuth2AuditLog)12 Client (io.jans.as.common.model.registration.Client)8 Response (javax.ws.rs.core.Response)8 WebApplicationException (javax.ws.rs.WebApplicationException)7 JSONException (org.json.JSONException)6 User (io.jans.as.common.model.common.User)5 InvalidJwtException (io.jans.as.model.exception.InvalidJwtException)5 AuthorizationGrant (io.jans.as.server.model.common.AuthorizationGrant)5 ExecutionContext (io.jans.as.server.model.common.ExecutionContext)5 JSONObject (org.json.JSONObject)5 SessionClient (io.jans.as.server.model.session.SessionClient)4 HttpServletResponse (javax.servlet.http.HttpServletResponse)4 JsonWebResponse (io.jans.as.model.token.JsonWebResponse)3 RegisterRequest (io.jans.as.client.RegisterRequest)2 SignatureAlgorithm (io.jans.as.model.crypto.signature.SignatureAlgorithm)2 DefaultErrorResponse (io.jans.as.model.error.DefaultErrorResponse)2 SessionId (io.jans.as.server.model.common.SessionId)2 ExternalUpdateTokenContext (io.jans.as.server.service.external.context.ExternalUpdateTokenContext)2 EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)2 ArrayList (java.util.ArrayList)2