use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.
the class IdentityBrokerService method performLogin.
@GET
@NoCache
@Path("/{provider_id}/login")
public Response performLogin(@PathParam("provider_id") String providerId, @QueryParam(LoginActionsService.SESSION_CODE) String code, @QueryParam("client_id") String clientId, @QueryParam(Constants.TAB_ID) String tabId, @QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) {
this.event.detail(Details.IDENTITY_PROVIDER, providerId);
if (isDebugEnabled()) {
logger.debugf("Sending authentication request to identity provider [%s].", providerId);
}
try {
AuthenticationSessionModel authSession = parseSessionCode(code, clientId, tabId);
ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerId);
if (identityProviderModel == null) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] not found.");
}
if (identityProviderModel.isLinkOnly()) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] is not allowed to perform a login.");
}
if (clientSessionCode != null && clientSessionCode.getClientSession() != null && loginHint != null) {
clientSessionCode.getClientSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
}
IdentityProviderFactory providerFactory = getIdentityProviderFactory(session, identityProviderModel);
IdentityProvider identityProvider = providerFactory.create(session, identityProviderModel);
Response response = identityProvider.performLogin(createAuthenticationRequest(providerId, clientSessionCode));
if (response != null) {
if (isDebugEnabled()) {
logger.debugf("Identity provider [%s] is going to send a request [%s].", identityProvider, response);
}
return response;
}
} catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId);
} catch (Exception e) {
return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerId);
}
return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
}
use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.
the class IdentityBrokerService method getToken.
private Response getToken(String providerId, boolean forceRetrieval) {
this.event.event(EventType.IDENTITY_PROVIDER_RETRIEVE_TOKEN);
try {
AuthenticationManager.AuthResult authResult = new AppAuthManager.BearerTokenAuthenticator(session).setRealm(realmModel).setConnection(clientConnection).setHeaders(request.getHttpHeaders()).authenticate();
if (authResult != null) {
AccessToken token = authResult.getToken();
ClientModel clientModel = authResult.getClient();
session.getContext().setClient(clientModel);
ClientModel brokerClient = realmModel.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
if (brokerClient == null) {
return corsResponse(forbidden("Realm has not migrated to support the broker token exchange service"), clientModel);
}
if (!canReadBrokerToken(token)) {
return corsResponse(forbidden("Client [" + clientModel.getClientId() + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
}
IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId);
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId);
if (identityProviderConfig.isStoreToken()) {
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerId);
if (identity == null) {
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel);
}
this.event.success();
return corsResponse(identityProvider.retrieveToken(session, identity), clientModel);
}
return corsResponse(badRequest("Identity Provider [" + providerId + "] does not support this operation."), clientModel);
}
return badRequest("Invalid token.");
} catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_OBTAIN_TOKEN, e, providerId);
} catch (Exception e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.UNEXPECTED_ERROR_RETRIEVING_TOKEN, e, providerId);
}
}
use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.
the class SAMLIdentityProvider method performLogin.
@Override
public Response performLogin(AuthenticationRequest request) {
try {
UriInfo uriInfo = request.getUriInfo();
RealmModel realm = request.getRealm();
String issuerURL = getEntityId(uriInfo, realm);
String destinationUrl = getConfig().getSingleSignOnServiceUrl();
String nameIDPolicyFormat = getConfig().getNameIDPolicyFormat();
if (nameIDPolicyFormat == null) {
nameIDPolicyFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get();
}
String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
String assertionConsumerServiceUrl = request.getRedirectUri();
if (getConfig().isPostBindingResponse()) {
protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
}
SAML2RequestedAuthnContextBuilder requestedAuthnContext = new SAML2RequestedAuthnContextBuilder().setComparison(getConfig().getAuthnContextComparisonType());
for (String authnContextClassRef : getAuthnContextClassRefUris()) requestedAuthnContext.addAuthnContextClassRef(authnContextClassRef);
for (String authnContextDeclRef : getAuthnContextDeclRefUris()) requestedAuthnContext.addAuthnContextDeclRef(authnContextDeclRef);
Integer attributeConsumingServiceIndex = getConfig().getAttributeConsumingServiceIndex();
String loginHint = getConfig().isLoginHint() ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
Boolean allowCreate = null;
if (getConfig().getConfig().get(SAMLIdentityProviderConfig.ALLOW_CREATE) == null || getConfig().isAllowCreate())
allowCreate = Boolean.TRUE;
SAML2AuthnRequestBuilder authnRequestBuilder = new SAML2AuthnRequestBuilder().assertionConsumerUrl(assertionConsumerServiceUrl).destination(destinationUrl).issuer(issuerURL).forceAuthn(getConfig().isForceAuthn()).protocolBinding(protocolBinding).nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat).setAllowCreate(allowCreate)).attributeConsumingServiceIndex(attributeConsumingServiceIndex).requestedAuthnContext(requestedAuthnContext).subject(loginHint);
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder(session).relayState(request.getState().getEncoded());
boolean postBinding = getConfig().isPostBindingAuthnRequest();
if (getConfig().isWantAuthnRequestsSigned()) {
KeyManager.ActiveRsaKey keys = session.keys().getActiveRsaKey(realm);
String keyName = getConfig().getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
binding.signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signatureAlgorithm(getSignatureAlgorithm()).signDocument();
if (!postBinding && getConfig().isAddExtensionsElementWithKeyInfo()) {
// Only include extension if REDIRECT binding and signing whole SAML protocol message
authnRequestBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
}
}
AuthnRequestType authnRequest = authnRequestBuilder.createAuthnRequest();
for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
authnRequest = it.next().beforeSendingLoginRequest(authnRequest, request.getAuthenticationSession());
}
if (authnRequest.getDestination() != null) {
destinationUrl = authnRequest.getDestination().toString();
}
// Save the current RequestID in the Auth Session as we need to verify it against the ID returned from the IdP
request.getAuthenticationSession().setClientNote(SamlProtocol.SAML_REQUEST_ID_BROKER, authnRequest.getID());
if (postBinding) {
return binding.postBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
} else {
return binding.redirectBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
}
} catch (Exception e) {
throw new IdentityBrokerException("Could not create authentication request.", e);
}
}
use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.
the class OIDCIdentityProvider method getFederatedIdentity.
@Override
public BrokeredIdentityContext getFederatedIdentity(String response) {
AccessTokenResponse tokenResponse = null;
try {
tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
} catch (IOException e) {
throw new IdentityBrokerException("Could not decode access token response.", e);
}
String accessToken = verifyAccessToken(tokenResponse);
String encodedIdToken = tokenResponse.getIdToken();
JsonWebToken idToken = validateToken(encodedIdToken);
try {
BrokeredIdentityContext identity = extractIdentity(tokenResponse, accessToken, idToken);
if (!identity.getId().equals(idToken.getSubject())) {
throw new IdentityBrokerException("Mismatch between the subject in the id_token and the subject from the user_info endpoint");
}
identity.getContextData().put(BROKER_NONCE_PARAM, idToken.getOtherClaims().get(OIDCLoginProtocol.NONCE_PARAM));
if (getConfig().isStoreToken()) {
if (tokenResponse.getExpiresIn() > 0) {
long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn();
tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
response = JsonSerialization.writeValueAsString(tokenResponse);
}
identity.setToken(response);
}
return identity;
} catch (Exception e) {
throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e);
}
}
use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.
the class OIDCIdentityProvider method validateToken.
protected JsonWebToken validateToken(String encodedToken, boolean ignoreAudience) {
if (encodedToken == null) {
throw new IdentityBrokerException("No token from server.");
}
JsonWebToken token;
try {
JWSInput jws = new JWSInput(encodedToken);
if (!verify(jws)) {
throw new IdentityBrokerException("token signature validation failed");
}
token = jws.readJsonContent(JsonWebToken.class);
} catch (JWSInputException e) {
throw new IdentityBrokerException("Invalid token", e);
}
String iss = token.getIssuer();
if (!token.isActive(getConfig().getAllowedClockSkew())) {
throw new IdentityBrokerException("Token is no longer valid");
}
if (!ignoreAudience && !token.hasAudience(getConfig().getClientId())) {
throw new IdentityBrokerException("Wrong audience from token.");
}
if (!ignoreAudience && (token.getIssuedFor() != null && !getConfig().getClientId().equals(token.getIssuedFor()))) {
throw new IdentityBrokerException("Token issued for does not match client id");
}
String trustedIssuers = getConfig().getIssuer();
if (trustedIssuers != null && trustedIssuers.length() > 0) {
String[] issuers = trustedIssuers.split(",");
for (String trustedIssuer : issuers) {
if (iss != null && iss.equals(trustedIssuer.trim())) {
return token;
}
}
throw new IdentityBrokerException("Wrong issuer from token. Got: " + iss + " expected: " + getConfig().getIssuer());
}
return token;
}
Aggregations