use of io.gravitee.am.common.exception.oauth2.InvalidRequestException in project gravitee-access-management by gravitee-io.
the class OAuth2AuthHandlerImpl method parseAuthorization.
private void parseAuthorization(RoutingContext context, Handler<AsyncResult<String>> handler) {
final HttpServerRequest request = context.request();
final String authorization = request.headers().get(io.vertx.core.http.HttpHeaders.AUTHORIZATION);
String authToken = null;
try {
if (authorization != null) {
// authorization header has been found check the value
int idx = authorization.indexOf(' ');
if (idx <= 0) {
handler.handle(Future.failedFuture(new InvalidRequestException("The access token must be sent using the Authorization header field")));
return;
}
if (!BEARER.equalsIgnoreCase(authorization.substring(0, idx))) {
handler.handle(Future.failedFuture(new HttpException(401)));
return;
}
authToken = authorization.substring(idx + 1);
} else {
// if no authorization header found, check authorization in body
authToken = request.getParam(ACCESS_TOKEN);
}
if (authToken == null) {
handler.handle(Future.failedFuture(new HttpException(401)));
return;
}
handler.handle(Future.succeededFuture(authToken));
} catch (RuntimeException e) {
handler.handle(Future.failedFuture(e));
}
}
use of io.gravitee.am.common.exception.oauth2.InvalidRequestException in project gravitee-access-management by gravitee-io.
the class AuthorizationCodeTokenGranter method parseRequest.
@Override
protected Single<TokenRequest> parseRequest(TokenRequest tokenRequest, Client client) {
MultiValueMap<String, String> parameters = tokenRequest.parameters();
String code = parameters.getFirst(Parameters.CODE);
if (code == null || code.isEmpty()) {
return Single.error(new InvalidRequestException("Missing parameter: code"));
}
return super.parseRequest(tokenRequest, client).flatMap(tokenRequest1 -> authorizationCodeService.remove(code, client).flatMap(authorizationCode -> authenticationFlowContextService.removeContext(authorizationCode.getTransactionId(), authorizationCode.getContextVersion()).onErrorResumeNext(error -> (exitOnError) ? Maybe.error(error) : Maybe.just(new AuthenticationFlowContext())).map(ctx -> {
checkRedirectUris(tokenRequest1, authorizationCode);
checkPKCE(tokenRequest1, authorizationCode);
// set resource owner
tokenRequest1.setSubject(authorizationCode.getSubject());
// set original scopes
tokenRequest1.setScopes(authorizationCode.getScopes());
// set authorization code initial request parameters (step1 of authorization code flow)
if (authorizationCode.getRequestParameters() != null) {
authorizationCode.getRequestParameters().forEach((key, value) -> tokenRequest1.parameters().putIfAbsent(key, value));
}
// set decoded authorization code to the current request
Map<String, Object> decodedAuthorizationCode = new HashMap<>();
decodedAuthorizationCode.put("code", authorizationCode.getCode());
decodedAuthorizationCode.put("transactionId", authorizationCode.getTransactionId());
tokenRequest1.setAuthorizationCode(decodedAuthorizationCode);
// store only the AuthenticationFlowContext.data attributes in order to simplify EL templating
// and provide an up to date set of data if the enrichAuthFlow Policy ius used multiple time in a step
// {#context.attributes['authFlow']['entry']}
tokenRequest1.getContext().put(ConstantKeys.AUTH_FLOW_CONTEXT_ATTRIBUTES_KEY, ctx.getData());
return tokenRequest1;
})).toSingle());
}
use of io.gravitee.am.common.exception.oauth2.InvalidRequestException in project gravitee-access-management by gravitee-io.
the class RefreshTokenGranter method parseRequest.
@Override
protected Single<TokenRequest> parseRequest(TokenRequest tokenRequest, Client client) {
String refreshToken = tokenRequest.parameters().getFirst(Parameters.REFRESH_TOKEN);
if (refreshToken == null || refreshToken.isEmpty()) {
return Single.error(new InvalidRequestException("A refresh token must be supplied."));
}
return super.parseRequest(tokenRequest, client).flatMap(tokenRequest1 -> getTokenService().refresh(refreshToken, tokenRequest, client).map(refreshToken1 -> {
// set resource owner
if (refreshToken1.getSubject() != null) {
tokenRequest1.setSubject(refreshToken1.getSubject());
}
// set scopes
// The requested scope MUST NOT include any scope
// not originally granted by the resource owner, and if omitted is
// treated as equal to the scope originally granted by the resource owner.
final Set<String> originalScopes = (refreshToken1.getScope() != null ? new HashSet(Arrays.asList(refreshToken1.getScope().split("\\s+"))) : null);
final Set<String> requestedScopes = tokenRequest1.getScopes();
if (requestedScopes == null || requestedScopes.isEmpty()) {
tokenRequest1.setScopes(originalScopes);
} else if (originalScopes != null && !originalScopes.isEmpty()) {
Set<String> filteredScopes = requestedScopes.stream().filter(requestedScope -> originalScopes.contains(requestedScope)).collect(Collectors.toSet());
tokenRequest1.setScopes(filteredScopes);
}
// set decoded refresh token to the current request
tokenRequest1.setRefreshToken(refreshToken1.getAdditionalInformation());
return tokenRequest1;
}));
}
use of io.gravitee.am.common.exception.oauth2.InvalidRequestException in project gravitee-access-management by gravitee-io.
the class CibaAuthenticationRequestResolver method validateLoginHintToken.
private Single<CibaAuthenticationRequest> validateLoginHintToken(CibaAuthenticationRequest authRequest, JWT jwt) {
try {
final Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
if (expirationTime != null) {
evaluateExp(expirationTime.toInstant().getEpochSecond(), Instant.now(), 0);
}
final JSONObject subIdObject = jwt.getJWTClaimsSet().getJSONObjectClaim("sub_id");
/*
sub_id is an object specifying the field identifying the user (through format entry)
Supported format : email and username
{
"sub_id": {
"format": "email",
"email": "user@acme.fr"
}
}
*/
final FilterCriteria criteria = new FilterCriteria();
criteria.setQuoteFilterValue(false);
final String field = subIdObject.getAsString("format");
if (!"email".equals(field) && !"username".equals(field)) {
return Single.error(new InvalidRequestException("Invalid hint, only email and username are supported"));
}
criteria.setFilterName(field);
criteria.setFilterValue(subIdObject.getAsString(field));
return userService.findByDomainAndCriteria(domain.getId(), criteria).flatMap(users -> {
if (users.size() != 1) {
LOGGER.warn("login_hint_token match multiple users or no one");
return Single.error(new InvalidRequestException("Invalid hint"));
}
authRequest.setSubject(users.get(0).getId());
return Single.just(authRequest);
});
} catch (ExpiredJWTException e) {
return Single.error(new ExpiredLoginHintTokenException("login_token_hint expired"));
} catch (ParseException e) {
// should never happen
LOGGER.warn("login_hint_token can't be read", e);
return Single.error(new ExpiredLoginHintTokenException("invalid login_token_hint"));
}
}
use of io.gravitee.am.common.exception.oauth2.InvalidRequestException in project gravitee-access-management by gravitee-io.
the class AuthorizationRequestParseIdTokenHintHandler method handle.
@Override
public void handle(RoutingContext routingContext) {
final Client client = routingContext.get(ConstantKeys.CLIENT_CONTEXT_KEY);
final String idTokenHint = getOAuthParameter(routingContext, Parameters.ID_TOKEN_HINT);
final String prompt = getOAuthParameter(routingContext, Parameters.PROMPT);
// if no id_token_hint parameter, continue;
if (idTokenHint == null) {
routingContext.next();
return;
}
// id_token_hint parameter should be present when prompt=none is used, if not respond with invalid_request exception
if (prompt == null) {
throw new InvalidRequestException("prompt parameter must be present when id_token_hint is used");
}
// retrieve prompt values (prompt parameter is a space delimited, case sensitive list of ASCII string values)
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
List<String> promptValues = Arrays.asList(prompt.split("\\s+"));
if (!promptValues.contains("none")) {
throw new InvalidRequestException("prompt=none must be present when id_token_hint is used");
}
// if client has not enabled this option, continue
if (!client.isSilentReAuthentication()) {
routingContext.next();
return;
}
// process silent re-authentication
extractUser(idTokenHint, client, h -> {
if (h.failed()) {
// if no user, continue
logger.debug("An error has occurred when extracting user from the ID token", h.cause());
routingContext.next();
return;
}
// set user in context and continue
io.gravitee.am.model.User endUser = h.result();
if (routingContext.user() == null) {
routingContext.setUser(User.newInstance(new io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User(endUser)));
routingContext.next();
return;
}
// if current user is not the same as the id token one, return login_required error
io.gravitee.am.model.User loggedInUser = ((io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User) routingContext.user().getDelegate()).getUser();
if (!loggedInUser.getId().equals(endUser.getId())) {
logger.debug("The End-User identified by the ID Token is not the same as the logged in End-User.");
routingContext.fail(new LoginRequiredException("Login required"));
} else {
routingContext.next();
}
});
}
Aggregations