Search in sources :

Example 1 with DeviceAuthorizationCacheControl

use of io.jans.as.server.model.common.DeviceAuthorizationCacheControl in project jans by JanssenProject.

the class DeviceAuthorizationAction method processUserCodeVerification.

/**
 * Processes user code introduced or loaded in the veritification page and redirects whether user code is correct
 * or return an error if there is something wrong.
 */
public void processUserCodeVerification() {
    SessionId session = sessionIdService.getSessionId();
    if (session == null) {
        facesMessages.add(FacesMessage.SEVERITY_WARN, languageBean.getMessage("error.errorEncountered"));
        return;
    }
    if (!preventBruteForcing(session)) {
        facesMessages.add(FacesMessage.SEVERITY_WARN, languageBean.getMessage("device.authorization.brute.forcing.msg"));
        return;
    }
    String userCode;
    if (StringUtils.isBlank(userCodePart1) && StringUtils.isBlank(userCodePart2)) {
        userCode = session.getSessionAttributes().get(SESSION_USER_CODE);
    } else {
        userCode = userCodePart1 + '-' + userCodePart2;
    }
    userCode = userCode.toUpperCase();
    if (!validateFormat(userCode)) {
        facesMessages.add(FacesMessage.SEVERITY_WARN, languageBean.getMessage("device.authorization.invalid.user.code"));
        return;
    }
    DeviceAuthorizationCacheControl cacheData = deviceAuthorizationService.getDeviceAuthzByUserCode(userCode);
    log.debug("Verifying device authorization cache data: {}", cacheData);
    String message = null;
    if (cacheData != null) {
        if (cacheData.getStatus() == DeviceAuthorizationStatus.PENDING) {
            session.getSessionAttributes().put(SESSION_USER_CODE, userCode);
            session.getSessionAttributes().remove(SESSION_LAST_ATTEMPT);
            session.getSessionAttributes().remove(SESSION_ATTEMPTS);
            sessionIdService.updateSessionId(session);
            redirectToAuthorization(cacheData);
        } else if (cacheData.getStatus() == DeviceAuthorizationStatus.DENIED) {
            message = languageBean.getMessage("device.authorization.access.denied.msg");
        } else {
            message = languageBean.getMessage("device.authorization.expired.code.msg");
        }
    } else {
        message = languageBean.getMessage("device.authorization.invalid.user.code");
    }
    if (message != null) {
        facesMessages.add(FacesMessage.SEVERITY_WARN, message);
    }
}
Also used : DeviceAuthorizationCacheControl(io.jans.as.server.model.common.DeviceAuthorizationCacheControl) SessionId(io.jans.as.server.model.common.SessionId)

Example 2 with DeviceAuthorizationCacheControl

use of io.jans.as.server.model.common.DeviceAuthorizationCacheControl 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 3 with DeviceAuthorizationCacheControl

use of io.jans.as.server.model.common.DeviceAuthorizationCacheControl in project jans by JanssenProject.

the class AuthorizeRestWebServiceValidator method validateRedirectUri.

public String validateRedirectUri(@NotNull Client client, @Nullable String redirectUri, @Nullable String state, @Nullable String deviceAuthzUserCode, @Nullable HttpServletRequest httpRequest, @NotNull AuthorizeErrorResponseType error) {
    if (appConfiguration.isFapi()) {
        // FAPI validator will check it in the request object.
        return redirectUri;
    }
    if (StringUtils.isNotBlank(deviceAuthzUserCode)) {
        DeviceAuthorizationCacheControl deviceAuthorizationCacheControl = deviceAuthorizationService.getDeviceAuthzByUserCode(deviceAuthzUserCode);
        redirectUri = deviceAuthorizationService.getDeviceAuthorizationPage(deviceAuthorizationCacheControl, client, state, httpRequest);
    } else {
        redirectUri = redirectionUriService.validateRedirectionUri(client, redirectUri);
    }
    if (StringUtils.isNotBlank(redirectUri)) {
        return redirectUri;
    }
    throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(errorResponseFactory.getErrorAsJson(error, state, "")).build());
}
Also used : DeviceAuthorizationCacheControl(io.jans.as.server.model.common.DeviceAuthorizationCacheControl) WebApplicationException(javax.ws.rs.WebApplicationException)

Example 4 with DeviceAuthorizationCacheControl

use of io.jans.as.server.model.common.DeviceAuthorizationCacheControl in project jans by JanssenProject.

the class TokenRestWebServiceImpl method processDeviceCodeGrantType.

/**
 * Processes token request for device code grant type.
 *
 * @param grantType      Grant type used, should be device code.
 * @param client         Client in process.
 * @param deviceCode     Device code generated in device authn request.
 * @param scope          Scope registered in device authn request.
 * @param request        HttpServletRequest
 * @param response       HttpServletResponse
 * @param oAuth2AuditLog OAuth2AuditLog
 */
private Response processDeviceCodeGrantType(final GrantType grantType, final Client client, final String deviceCode, String scope, final HttpServletRequest request, final HttpServletResponse response, final OAuth2AuditLog oAuth2AuditLog) {
    if (!TokenParamsValidator.validateGrantType(grantType, client.getGrantTypes(), appConfiguration.getGrantTypesSupported())) {
        return response(error(400, TokenErrorResponseType.INVALID_GRANT, "Grant types are invalid."), oAuth2AuditLog);
    }
    log.debug("Attempting to find authorizationGrant by deviceCode: '{}'", deviceCode);
    final DeviceCodeGrant deviceCodeGrant = authorizationGrantList.getDeviceCodeGrant(deviceCode);
    log.trace("DeviceCodeGrant : '{}'", deviceCodeGrant);
    if (deviceCodeGrant != null) {
        if (!deviceCodeGrant.getClientId().equals(client.getClientId())) {
            throw new WebApplicationException(response(error(400, TokenErrorResponseType.INVALID_GRANT, REASON_CLIENT_NOT_AUTHORIZED), oAuth2AuditLog));
        }
        RefreshToken refToken = createRefreshToken(request, client, scope, deviceCodeGrant, null);
        final ExecutionContext executionContext = new ExecutionContext(request, response);
        executionContext.setGrant(deviceCodeGrant);
        executionContext.setCertAsPem(request.getHeader(X_CLIENTCERT));
        executionContext.setClient(client);
        executionContext.setAppConfiguration(appConfiguration);
        executionContext.setAttributeService(attributeService);
        AccessToken accessToken = deviceCodeGrant.createAccessToken(executionContext);
        ExternalUpdateTokenContext context = new ExternalUpdateTokenContext(request, deviceCodeGrant, client, appConfiguration, attributeService);
        context.setExecutionContext(executionContext);
        executionContext.setIncludeIdTokenClaims(false);
        executionContext.setPreProcessing(null);
        executionContext.setPostProcessor(externalUpdateTokenService.buildModifyIdTokenProcessor(context));
        IdToken idToken = deviceCodeGrant.createIdToken(null, null, accessToken, refToken, null, executionContext);
        deviceCodeGrant.checkScopesPolicy(scope);
        log.info("Device authorization in token endpoint processed and return to the client, device_code: {}", deviceCodeGrant.getDeviceCode());
        oAuth2AuditLog.updateOAuth2AuditLog(deviceCodeGrant, true);
        grantService.removeByCode(deviceCodeGrant.getDeviceCode());
        return Response.ok().entity(getJSonResponse(accessToken, accessToken.getTokenType(), accessToken.getExpiresIn(), refToken, scope, idToken)).build();
    } else {
        final DeviceAuthorizationCacheControl cacheData = deviceAuthorizationService.getDeviceAuthzByDeviceCode(deviceCode);
        log.trace("DeviceAuthorizationCacheControl data : '{}'", cacheData);
        if (cacheData == null) {
            log.debug("The authentication request has expired for deviceCode: '{}'", deviceCode);
            throw new WebApplicationException(response(error(400, TokenErrorResponseType.EXPIRED_TOKEN, "The authentication request has expired."), oAuth2AuditLog));
        }
        if (!cacheData.getClient().getClientId().equals(client.getClientId())) {
            throw new WebApplicationException(response(error(400, TokenErrorResponseType.INVALID_GRANT, REASON_CLIENT_NOT_AUTHORIZED), oAuth2AuditLog));
        }
        long currentTime = new Date().getTime();
        Long lastAccess = cacheData.getLastAccessControl();
        if (lastAccess == null) {
            lastAccess = currentTime;
        }
        cacheData.setLastAccessControl(currentTime);
        deviceAuthorizationService.saveInCache(cacheData, true, true);
        if (cacheData.getStatus() == DeviceAuthorizationStatus.PENDING) {
            int intervalSeconds = appConfiguration.getBackchannelAuthenticationResponseInterval();
            long timeFromLastAccess = currentTime - lastAccess;
            if (timeFromLastAccess > intervalSeconds * 1000) {
                log.debug("Access hasn't been granted yet for deviceCode: '{}'", deviceCode);
                throw new WebApplicationException(response(error(400, TokenErrorResponseType.AUTHORIZATION_PENDING, "User hasn't answered yet"), oAuth2AuditLog));
            } else {
                log.debug("Slow down protection deviceCode: '{}'", deviceCode);
                throw new WebApplicationException(response(error(400, TokenErrorResponseType.SLOW_DOWN, "Client is asking too fast the token."), oAuth2AuditLog));
            }
        }
        if (cacheData.getStatus() == DeviceAuthorizationStatus.DENIED) {
            log.debug("The end-user denied the authorization request for deviceCode: '{}'", deviceCode);
            throw new WebApplicationException(response(error(400, TokenErrorResponseType.ACCESS_DENIED, "The end-user denied the authorization request."), oAuth2AuditLog));
        }
        log.debug("The authentication request has expired for deviceCode: '{}'", deviceCode);
        throw new WebApplicationException(response(error(400, TokenErrorResponseType.EXPIRED_TOKEN, "The authentication request has expired"), oAuth2AuditLog));
    }
}
Also used : IdToken(io.jans.as.server.model.common.IdToken) RefreshToken(io.jans.as.server.model.common.RefreshToken) ExecutionContext(io.jans.as.server.model.common.ExecutionContext) WebApplicationException(javax.ws.rs.WebApplicationException) ExternalUpdateTokenContext(io.jans.as.server.service.external.context.ExternalUpdateTokenContext) DeviceAuthorizationCacheControl(io.jans.as.server.model.common.DeviceAuthorizationCacheControl) AccessToken(io.jans.as.server.model.common.AccessToken) DeviceCodeGrant(io.jans.as.server.model.common.DeviceCodeGrant) Date(java.util.Date)

Example 5 with DeviceAuthorizationCacheControl

use of io.jans.as.server.model.common.DeviceAuthorizationCacheControl in project jans by JanssenProject.

the class AuthorizeService method processDeviceAuthDeniedResponse.

private void processDeviceAuthDeniedResponse(Map<String, String> sessionAttribute) {
    String userCode = sessionAttribute.get(DeviceAuthorizationService.SESSION_USER_CODE);
    DeviceAuthorizationCacheControl cacheData = deviceAuthorizationService.getDeviceAuthzByUserCode(userCode);
    if (cacheData != null && cacheData.getStatus() == DeviceAuthorizationStatus.PENDING) {
        cacheData.setStatus(DeviceAuthorizationStatus.DENIED);
        deviceAuthorizationService.saveInCache(cacheData, true, false);
        deviceAuthorizationService.removeDeviceAuthRequestInCache(userCode, null);
    }
}
Also used : DeviceAuthorizationCacheControl(io.jans.as.server.model.common.DeviceAuthorizationCacheControl)

Aggregations

DeviceAuthorizationCacheControl (io.jans.as.server.model.common.DeviceAuthorizationCacheControl)5 WebApplicationException (javax.ws.rs.WebApplicationException)3 Client (io.jans.as.common.model.registration.Client)1 VERIFICATION_URI (io.jans.as.model.authorize.DeviceAuthorizationResponseParam.VERIFICATION_URI)1 OAuth2AuditLog (io.jans.as.server.model.audit.OAuth2AuditLog)1 AccessToken (io.jans.as.server.model.common.AccessToken)1 DeviceAuthorizationStatus (io.jans.as.server.model.common.DeviceAuthorizationStatus)1 DeviceCodeGrant (io.jans.as.server.model.common.DeviceCodeGrant)1 ExecutionContext (io.jans.as.server.model.common.ExecutionContext)1 IdToken (io.jans.as.server.model.common.IdToken)1 RefreshToken (io.jans.as.server.model.common.RefreshToken)1 SessionId (io.jans.as.server.model.common.SessionId)1 SessionClient (io.jans.as.server.model.session.SessionClient)1 ExternalUpdateTokenContext (io.jans.as.server.service.external.context.ExternalUpdateTokenContext)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 JSONException (org.json.JSONException)1