use of io.gravitee.am.common.exception.oauth2.InvalidTokenException in project gravitee-access-management by gravitee-io.
the class UserInfoEndpointHandlerTest method shouldNotInvokeUserEndpoint_unknownToken.
@Test
public void shouldNotInvokeUserEndpoint_unknownToken() throws Exception {
JWT jwt = new JWT();
jwt.setAud("client-id");
router.route().order(-1).handler(createOAuth2AuthHandler(oAuth2AuthProvider(new InvalidTokenException())));
testRequest(HttpMethod.GET, "/userinfo", req -> req.putHeader(HttpHeaders.AUTHORIZATION, "Bearer test-token"), HttpStatusCode.UNAUTHORIZED_401, "Unauthorized", null);
}
use of io.gravitee.am.common.exception.oauth2.InvalidTokenException in project gravitee-access-management by gravitee-io.
the class UserInfoEndpoint method handle.
@Override
public void handle(RoutingContext context) {
JWT accessToken = context.get(ConstantKeys.TOKEN_CONTEXT_KEY);
Client client = context.get(ConstantKeys.CLIENT_CONTEXT_KEY);
String subject = accessToken.getSub();
userService.findById(subject).switchIfEmpty(Maybe.error(new InvalidTokenException("No user found for this token"))).flatMapSingle(user -> enhance(user, accessToken)).map(user -> processClaims(user, accessToken)).flatMap(claims -> {
if (!expectSignedOrEncryptedUserInfo(client)) {
context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
return Single.just(Json.encodePrettily(claims));
} else {
context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JWT);
JWT jwt = new JWT(claims);
jwt.setIss(openIDDiscoveryService.getIssuer(UriBuilderRequest.resolveProxyRequest(context)));
jwt.setSub(accessToken.getSub());
jwt.setAud(accessToken.getAud());
jwt.setIat(new Date().getTime() / 1000l);
jwt.setExp(accessToken.getExp() / 1000l);
return // Sign if needed, else return unsigned JWT
jwtService.encodeUserinfo(jwt, client).flatMap(// Encrypt if needed, else return JWT
userinfo -> jweService.encryptUserinfo(userinfo, client));
}
}).subscribe(buffer -> context.response().putHeader(HttpHeaders.CACHE_CONTROL, "no-store").putHeader(HttpHeaders.PRAGMA, "no-cache").end(buffer), error -> context.fail(error));
}
use of io.gravitee.am.common.exception.oauth2.InvalidTokenException in project gravitee-access-management by gravitee-io.
the class AuthenticationRequestServiceTest method shouldNotUpdateStatus_InvalidSignature.
@Test
public void shouldNotUpdateStatus_InvalidSignature() {
final String STATE = "state";
final String EXTERNAL_ID = "externalId";
final boolean requestValidated = new Random().nextBoolean();
AuthenticationDeviceNotifierProvider provider = mock(AuthenticationDeviceNotifierProvider.class);
when(notifierManager.getAuthDeviceNotifierProviders()).thenReturn(List.of(provider));
when(provider.extractUserResponse(any())).thenReturn(Single.just(Optional.of(new ADUserResponse(EXTERNAL_ID, STATE, requestValidated))));
final JWT stateJwt = new JWT();
stateJwt.setJti(EXTERNAL_ID);
when(this.jwtService.decode(STATE)).thenReturn(Single.just(stateJwt));
when(this.clientService.findByClientId(any())).thenReturn(Maybe.just(new Client()));
when(this.jwtService.decodeAndVerify(anyString(), any(Client.class))).thenReturn(Single.error(new InvalidTokenException()));
final ADCallbackContext context = new ADCallbackContext(MultiMap.caseInsensitiveMultiMap(), MultiMap.caseInsensitiveMultiMap());
final TestObserver<Void> observer = this.service.validateUserResponse(context).test();
observer.awaitTerminalEvent();
observer.assertError(InvalidRequestException.class);
verify(clientService).findByClientId(any());
verify(requestRepository, never()).updateStatus(any(), any());
}
use of io.gravitee.am.common.exception.oauth2.InvalidTokenException in project gravitee-access-management by gravitee-io.
the class OAuth2AuthHandlerImpl method handle.
@Override
public void handle(RoutingContext context) {
parseAuthorization(context, parseHandler -> {
if (parseHandler.failed()) {
processException(context, parseHandler.cause());
return;
}
final String jwtToken = parseHandler.result();
// set raw token to the current context
if (extractRawToken) {
context.put(ConstantKeys.RAW_TOKEN_CONTEXT_KEY, jwtToken);
}
oAuth2AuthProvider.decodeToken(jwtToken, offlineVerification, handler -> {
if (handler.failed()) {
processException(context, handler.cause());
return;
}
OAuth2AuthResponse response = handler.result();
JWT token = response.getToken();
Client client = response.getClient();
// set token to the current context
if (extractToken) {
context.put(ConstantKeys.TOKEN_CONTEXT_KEY, token);
}
// set client to the current context
if (extractClient) {
context.put(ConstantKeys.CLIENT_CONTEXT_KEY, client);
}
// check if current subject can access its own resources
if (selfResource) {
final String resourceId = context.request().getParam(resourceParameter);
if (resourceId != null && resourceId.equals(token.getSub())) {
if (resourceRequiredScope == null || token.hasScope(resourceRequiredScope)) {
context.next();
return;
}
}
}
if (forceEndUserToken) {
if (token.getSub().equals(token.getAud())) {
// token for end user must not contain clientId as subject
processException(context, new InvalidTokenException("The access token was not issued for an End-User"));
return;
}
}
if (forceClientToken) {
if (!token.getSub().equals(token.getAud())) {
// token for end user must not contain clientId as subject
processException(context, new InvalidTokenException("The access token was not issued for a Client"));
return;
}
}
// check required scope
if (requiredScope != null) {
if (!token.hasScope(requiredScope)) {
processException(context, new InsufficientScopeException("Invalid access token scopes. The access token should have at least '" + requiredScope + "' scope"));
return;
}
}
context.next();
});
});
}
use of io.gravitee.am.common.exception.oauth2.InvalidTokenException in project gravitee-access-management by gravitee-io.
the class IntrospectionTokenServiceImpl method introspect.
@Override
public Single<JWT> introspect(String token, boolean offlineVerification) {
return jwtService.decode(token).flatMapMaybe(jwt -> clientService.findByDomainAndClientId(jwt.getDomain(), jwt.getAud())).switchIfEmpty(Maybe.error(new InvalidTokenException("Invalid or unknown client for this token"))).flatMapSingle(client -> jwtService.decodeAndVerify(token, client)).flatMap(jwt -> {
// or if the token has just been created (could not be in database so far because of async database storing process delay)
if (offlineVerification || Instant.now().isBefore(Instant.ofEpochSecond(jwt.getIat() + OFFLINE_VERIFICATION_TIMER_SECONDS))) {
return Single.just(jwt);
}
// check if token is not revoked
return accessTokenRepository.findByToken(jwt.getJti()).switchIfEmpty(Single.error(new InvalidTokenException("The token is invalid", "Token with JTI [" + jwt.getJti() + "] not found in the database", jwt))).map(accessToken -> {
if (accessToken.getExpireAt().before(new Date())) {
throw new InvalidTokenException("The token expired", "Token with JTI [" + jwt.getJti() + "] is expired", jwt);
}
return jwt;
});
}).onErrorResumeNext(ex -> {
if (ex instanceof JWTException) {
LOGGER.debug("An error occurs while decoding JWT access token : {}", token, ex);
return Single.error(new InvalidTokenException(ex.getMessage(), ex));
}
if (ex instanceof InvalidTokenException) {
InvalidTokenException invalidTokenException = (InvalidTokenException) ex;
String details = invalidTokenException.getDetails();
JWT jwt = invalidTokenException.getJwt();
LOGGER.debug("An error occurs while checking JWT access token validity: {}\n\t - details: {}\n\t - decoded jwt: {}", token, details != null ? details : "none", jwt != null ? jwt.toString() : "{}", invalidTokenException);
}
return Single.error(ex);
});
}
Aggregations