Search in sources :

Example 1 with DeviceCodeGrant

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

Aggregations

AccessToken (io.jans.as.server.model.common.AccessToken)1 DeviceAuthorizationCacheControl (io.jans.as.server.model.common.DeviceAuthorizationCacheControl)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 ExternalUpdateTokenContext (io.jans.as.server.service.external.context.ExternalUpdateTokenContext)1 Date (java.util.Date)1 WebApplicationException (javax.ws.rs.WebApplicationException)1