use of org.keycloak.representations.JsonWebToken in project keycloak by keycloak.
the class ClientRegistrationTokenUtils method verifyToken.
public static TokenVerification verifyToken(KeycloakSession session, RealmModel realm, String token) {
if (token == null) {
return TokenVerification.error(new RuntimeException("Missing token"));
}
String kid;
JsonWebToken jwt;
try {
TokenVerifier<JsonWebToken> verifier = TokenVerifier.create(token, JsonWebToken.class).withChecks(new TokenVerifier.RealmUrlCheck(getIssuer(session, realm)), TokenVerifier.IS_ACTIVE);
SignatureVerifierContext verifierContext = session.getProvider(SignatureProvider.class, verifier.getHeader().getAlgorithm().name()).verifier(verifier.getHeader().getKeyId());
verifier.verifierContext(verifierContext);
kid = verifierContext.getKid();
verifier.verify();
jwt = verifier.getToken();
} catch (VerificationException e) {
return TokenVerification.error(new RuntimeException("Failed decode token", e));
}
if (!(TokenUtil.TOKEN_TYPE_BEARER.equals(jwt.getType()) || TYPE_INITIAL_ACCESS_TOKEN.equals(jwt.getType()) || TYPE_REGISTRATION_ACCESS_TOKEN.equals(jwt.getType()))) {
return TokenVerification.error(new RuntimeException("Invalid type of token"));
}
return TokenVerification.success(kid, jwt);
}
use of org.keycloak.representations.JsonWebToken in project keycloak by keycloak.
the class DefaultTokenExchangeProvider method tokenExchange.
protected Response tokenExchange() {
UserModel tokenUser = null;
UserSessionModel tokenSession = null;
AccessToken token = null;
String subjectToken = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN);
if (subjectToken != null) {
String subjectTokenType = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
String realmIssuerUrl = Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName());
String subjectIssuer = formParams.getFirst(OAuth2Constants.SUBJECT_ISSUER);
if (subjectIssuer == null && OAuth2Constants.JWT_TOKEN_TYPE.equals(subjectTokenType)) {
try {
JWSInput jws = new JWSInput(subjectToken);
JsonWebToken jwt = jws.readJsonContent(JsonWebToken.class);
subjectIssuer = jwt.getIssuer();
} catch (JWSInputException e) {
event.detail(Details.REASON, "unable to parse jwt subject_token");
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token type, must be access token", Response.Status.BAD_REQUEST);
}
}
if (subjectIssuer != null && !realmIssuerUrl.equals(subjectIssuer)) {
event.detail(OAuth2Constants.SUBJECT_ISSUER, subjectIssuer);
return exchangeExternalToken(subjectIssuer, subjectToken);
}
if (subjectTokenType != null && !subjectTokenType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE)) {
event.detail(Details.REASON, "subject_token supports access tokens only");
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token type, must be access token", Response.Status.BAD_REQUEST);
}
AuthenticationManager.AuthResult authResult = AuthenticationManager.verifyIdentityToken(session, realm, session.getContext().getUri(), clientConnection, true, true, null, false, subjectToken, headers);
if (authResult == null) {
event.detail(Details.REASON, "subject_token validation failure");
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.BAD_REQUEST);
}
tokenUser = authResult.getUser();
tokenSession = authResult.getSession();
token = authResult.getToken();
}
String requestedSubject = formParams.getFirst(OAuth2Constants.REQUESTED_SUBJECT);
if (requestedSubject != null) {
event.detail(Details.REQUESTED_SUBJECT, requestedSubject);
UserModel requestedUser = session.users().getUserByUsername(realm, requestedSubject);
if (requestedUser == null) {
requestedUser = session.users().getUserById(realm, requestedSubject);
}
if (requestedUser == null) {
// We always returned access denied to avoid username fishing
event.detail(Details.REASON, "requested_subject not found");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
if (token != null) {
event.detail(Details.IMPERSONATOR, tokenUser.getUsername());
// for this case, the user represented by the token, must have permission to impersonate.
AdminAuth auth = new AdminAuth(realm, token, tokenUser, client);
if (!AdminPermissions.evaluator(session, realm, auth).users().canImpersonate(requestedUser)) {
event.detail(Details.REASON, "subject not allowed to impersonate");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
} else {
// to impersonate
if (client.isPublicClient()) {
event.detail(Details.REASON, "public clients not allowed");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
if (!AdminPermissions.management(session, realm).users().canClientImpersonate(client, requestedUser)) {
event.detail(Details.REASON, "client not allowed to impersonate");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
}
tokenSession = session.sessions().createUserSession(realm, requestedUser, requestedUser.getUsername(), clientConnection.getRemoteAddr(), "impersonate", false, null, null);
if (tokenUser != null) {
tokenSession.setNote(IMPERSONATOR_ID.toString(), tokenUser.getId());
tokenSession.setNote(IMPERSONATOR_USERNAME.toString(), tokenUser.getUsername());
}
tokenUser = requestedUser;
}
String requestedIssuer = formParams.getFirst(OAuth2Constants.REQUESTED_ISSUER);
if (requestedIssuer == null) {
return exchangeClientToClient(tokenUser, tokenSession);
} else {
try {
return exchangeToIdentityProvider(tokenUser, tokenSession, requestedIssuer);
} finally {
if (subjectToken == null) {
// we are naked! So need to clean up user session
try {
session.sessions().removeUserSession(realm, tokenSession);
} catch (Exception ignore) {
}
}
}
}
}
use of org.keycloak.representations.JsonWebToken in project keycloak by keycloak.
the class AbstractClientPoliciesTest method createSignedRequestToken.
// Signed JWT for client authentication utility
protected String createSignedRequestToken(String clientId, PrivateKey privateKey, PublicKey publicKey, String algorithm) {
JsonWebToken jwt = createRequestToken(clientId, getRealmInfoUrl());
String kid = KeyUtils.createKeyId(publicKey);
SignatureSignerContext signer = oauth.createSigner(privateKey, kid, algorithm);
return new JWSBuilder().kid(kid).jsonContent(jwt).sign(signer);
}
use of org.keycloak.representations.JsonWebToken in project keycloak by keycloak.
the class AbstractClientPoliciesTest method createRequestToken.
private JsonWebToken createRequestToken(String clientId, String realmInfoUrl) {
JsonWebToken reqToken = new JsonWebToken();
reqToken.id(AdapterUtils.generateId());
reqToken.issuer(clientId);
reqToken.subject(clientId);
reqToken.audience(realmInfoUrl);
int now = Time.currentTime();
reqToken.iat(Long.valueOf(now));
reqToken.exp(Long.valueOf(now + 10));
reqToken.nbf(Long.valueOf(now));
return reqToken;
}
use of org.keycloak.representations.JsonWebToken in project keycloak by keycloak.
the class ClientAuthSignedJWTTest method createRequestToken.
private JsonWebToken createRequestToken(String clientId, String realmInfoUrl) {
JsonWebToken reqToken = new JsonWebToken();
reqToken.id(AdapterUtils.generateId());
reqToken.issuer(clientId);
reqToken.subject(clientId);
reqToken.audience(realmInfoUrl);
int now = Time.currentTime();
reqToken.issuedAt(now);
reqToken.expiration(now + 10);
reqToken.notBefore(now);
return reqToken;
}
Aggregations