use of org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor in project keycloak by keycloak.
the class SAMLIdentityProvider method buildLogoutRequest.
protected LogoutRequestType buildLogoutRequest(UserSessionModel userSession, UriInfo uriInfo, RealmModel realm, String singleLogoutServiceUrl, NodeGenerator... extensions) throws ConfigurationException {
SAML2LogoutRequestBuilder logoutBuilder = new SAML2LogoutRequestBuilder().assertionExpiration(realm.getAccessCodeLifespan()).issuer(getEntityId(uriInfo, realm)).sessionIndex(userSession.getNote(SAMLEndpoint.SAML_FEDERATED_SESSION_INDEX)).nameId(NameIDType.deserializeFromString(userSession.getNote(SAMLEndpoint.SAML_FEDERATED_SUBJECT_NAMEID))).destination(singleLogoutServiceUrl);
LogoutRequestType logoutRequest = logoutBuilder.createLogoutRequest();
for (NodeGenerator extension : extensions) {
logoutBuilder.addExtension(extension);
}
for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
logoutRequest = it.next().beforeSendingLogoutRequest(logoutRequest, userSession, null);
}
return logoutRequest;
}
use of org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor 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.protocol.saml.preprocessor.SamlAuthenticationPreprocessor in project keycloak by keycloak.
the class IdentityBrokerService method authenticated.
public Response authenticated(BrokeredIdentityContext context) {
IdentityProviderModel identityProviderConfig = context.getIdpConfig();
AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
String providerId = identityProviderConfig.getAlias();
if (!identityProviderConfig.isStoreToken()) {
if (isDebugEnabled()) {
logger.debugf("Token will not be stored for identity provider [%s].", providerId);
}
context.setToken(null);
}
StatusResponseType loginResponse = (StatusResponseType) context.getContextData().get(SAMLEndpoint.SAML_LOGIN_RESPONSE);
if (loginResponse != null) {
for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
loginResponse = it.next().beforeProcessingLoginResponse(loginResponse, authenticationSession);
}
}
session.getContext().setClient(authenticationSession.getClient());
context.getIdp().preprocessFederatedIdentity(session, realmModel, context);
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
realmModel.getIdentityProviderMappersByAliasStream(context.getIdpConfig().getAlias()).forEach(mapper -> {
IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
target.preprocessFederatedIdentity(session, realmModel, mapper, context);
});
FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(), context.getUsername(), context.getToken());
this.event.event(EventType.IDENTITY_PROVIDER_LOGIN).detail(Details.REDIRECT_URI, authenticationSession.getRedirectUri()).detail(Details.IDENTITY_PROVIDER, providerId).detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
boolean shouldMigrateId = false;
// try to find the user using legacy ID
if (federatedUser == null && context.getLegacyId() != null) {
federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
shouldMigrateId = true;
}
// Check if federatedUser is already authenticated (this means linking social into existing federatedUser account)
UserSessionModel userSession = new AuthenticationSessionManager(session).getUserSession(authenticationSession);
if (shouldPerformAccountLinking(authenticationSession, userSession, providerId)) {
return performAccountLinking(authenticationSession, userSession, context, federatedIdentityModel, federatedUser);
}
if (federatedUser == null) {
logger.debugf("Federated user not found for provider '%s' and broker username '%s'", providerId, context.getUsername());
String username = context.getModelUsername();
if (username == null) {
if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isBlank(context.getEmail())) {
username = context.getEmail();
} else if (context.getUsername() == null) {
username = context.getIdpConfig().getAlias() + "." + context.getId();
} else {
username = context.getUsername();
}
}
username = username.trim();
context.setModelUsername(username);
SerializedBrokeredIdentityContext ctx0 = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
if (ctx0 != null) {
SerializedBrokeredIdentityContext ctx1 = SerializedBrokeredIdentityContext.serialize(context);
ctx1.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.NESTED_FIRST_BROKER_CONTEXT);
logger.warnv("Nested first broker flow detected: {0} -> {1}", ctx0.getIdentityProviderId(), ctx1.getIdentityProviderId());
logger.debug("Resuming last execution");
URI redirect = new AuthenticationFlowURLHelper(session, realmModel, session.getContext().getUri()).getLastExecutionUrl(authenticationSession);
return Response.status(Status.FOUND).location(redirect).build();
}
logger.debug("Redirecting to flow for firstBrokerLogin");
boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN));
// Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed
AuthenticationProcessor.resetFlow(authenticationSession, LoginActionsService.FIRST_BROKER_LOGIN_PATH);
// Set the FORWARDED_PASSIVE_LOGIN note (if needed) after resetting the session so it is not lost.
if (forwardedPassiveLogin) {
authenticationSession.setAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN, "true");
}
SerializedBrokeredIdentityContext ctx = SerializedBrokeredIdentityContext.serialize(context);
ctx.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
URI redirect = LoginActionsService.firstBrokerLoginProcessor(session.getContext().getUri()).queryParam(Constants.CLIENT_ID, authenticationSession.getClient().getClientId()).queryParam(Constants.TAB_ID, authenticationSession.getTabId()).build(realmModel.getName());
return Response.status(302).location(redirect).build();
} else {
Response response = validateUser(authenticationSession, federatedUser, realmModel);
if (response != null) {
return response;
}
updateFederatedIdentity(context, federatedUser);
if (shouldMigrateId) {
migrateFederatedIdentityId(context, federatedUser);
}
authenticationSession.setAuthenticatedUser(federatedUser);
return finishOrRedirectToPostBrokerLogin(authenticationSession, context, false);
}
}
use of org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor in project keycloak by keycloak.
the class SamlProtocol method createLogoutRequest.
protected LogoutRequestType createLogoutRequest(String logoutUrl, AuthenticatedClientSessionModel clientSession, ClientModel client, NodeGenerator... extensions) throws ConfigurationException {
// build userPrincipal with subject used at login
SAML2LogoutRequestBuilder logoutBuilder = new SAML2LogoutRequestBuilder().assertionExpiration(realm.getAccessCodeLifespan()).issuer(getResponseIssuer(realm)).userPrincipal(clientSession.getNote(SAML_NAME_ID), clientSession.getNote(SAML_NAME_ID_FORMAT)).destination(logoutUrl);
String sessionIndex = SamlSessionUtils.getSessionIndex(clientSession);
logoutBuilder.sessionIndex(sessionIndex);
for (NodeGenerator extension : extensions) {
logoutBuilder.addExtension(extension);
}
LogoutRequestType logoutRequest = logoutBuilder.createLogoutRequest();
for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
logoutRequest = it.next().beforeSendingLogoutRequest(logoutRequest, clientSession.getUserSession(), clientSession);
}
return logoutRequest;
}
Aggregations