use of org.wso2.carbon.identity.application.authentication.framework.AuthenticationFlowHandler in project carbon-identity-framework by wso2.
the class FrameworkServiceComponent method setAuthenticator.
@Reference(name = "application.authenticator", service = ApplicationAuthenticator.class, cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.DYNAMIC, unbind = "unsetAuthenticator")
protected void setAuthenticator(ApplicationAuthenticator authenticator) {
FrameworkServiceDataHolder.getInstance().getAuthenticators().add(authenticator);
Property[] configProperties = null;
List<Property> configurationProperties = authenticator.getConfigurationProperties();
if (configurationProperties == null) {
configurationProperties = new ArrayList<>();
}
if (authenticator instanceof AuthenticationFlowHandler) {
Property handlerProperty = new Property();
handlerProperty.setName(IS_HANDLER);
handlerProperty.setValue(TRUE);
configurationProperties.add(handlerProperty);
}
if (!configurationProperties.isEmpty()) {
configProperties = configurationProperties.toArray(new Property[0]);
}
if ((authenticator instanceof LocalApplicationAuthenticator) || (authenticator instanceof AuthenticationFlowHandler)) {
LocalAuthenticatorConfig localAuthenticatorConfig = new LocalAuthenticatorConfig();
localAuthenticatorConfig.setName(authenticator.getName());
localAuthenticatorConfig.setProperties(configProperties);
localAuthenticatorConfig.setDisplayName(authenticator.getFriendlyName());
localAuthenticatorConfig.setTags(authenticator.getTags());
AuthenticatorConfig fileBasedConfig = getAuthenticatorConfig(authenticator.getName());
localAuthenticatorConfig.setEnabled(fileBasedConfig.isEnabled());
ApplicationAuthenticatorService.getInstance().addLocalAuthenticator(localAuthenticatorConfig);
} else if (authenticator instanceof FederatedApplicationAuthenticator) {
FederatedAuthenticatorConfig federatedAuthenticatorConfig = new FederatedAuthenticatorConfig();
federatedAuthenticatorConfig.setName(authenticator.getName());
federatedAuthenticatorConfig.setProperties(configProperties);
federatedAuthenticatorConfig.setDisplayName(authenticator.getFriendlyName());
federatedAuthenticatorConfig.setTags(authenticator.getTags());
ApplicationAuthenticatorService.getInstance().addFederatedAuthenticator(federatedAuthenticatorConfig);
} else if (authenticator instanceof RequestPathApplicationAuthenticator) {
RequestPathAuthenticatorConfig reqPathAuthenticatorConfig = new RequestPathAuthenticatorConfig();
reqPathAuthenticatorConfig.setName(authenticator.getName());
reqPathAuthenticatorConfig.setProperties(configProperties);
reqPathAuthenticatorConfig.setDisplayName(authenticator.getFriendlyName());
reqPathAuthenticatorConfig.setTags(authenticator.getTags());
AuthenticatorConfig fileBasedConfig = getAuthenticatorConfig(authenticator.getName());
reqPathAuthenticatorConfig.setEnabled(fileBasedConfig.isEnabled());
ApplicationAuthenticatorService.getInstance().addRequestPathAuthenticator(reqPathAuthenticatorConfig);
}
if (log.isDebugEnabled()) {
log.debug("Added application authenticator : " + authenticator.getName());
}
}
use of org.wso2.carbon.identity.application.authentication.framework.AuthenticationFlowHandler in project carbon-identity-framework by wso2.
the class DefaultStepHandler method handle.
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws FrameworkException {
if (context.getAnalyticsData(FrameworkConstants.AnalyticsData.CURRENT_AUTHENTICATOR_START_TIME) == null) {
context.setAnalyticsData(FrameworkConstants.AnalyticsData.CURRENT_AUTHENTICATOR_START_TIME, System.currentTimeMillis());
}
StepConfig stepConfig = context.getSequenceConfig().getStepMap().get(context.getCurrentStep());
List<AuthenticatorConfig> authConfigList = stepConfig.getAuthenticatorList();
String authenticatorNames = FrameworkUtils.getAuthenticatorIdPMappingString(authConfigList);
String loginPage = ConfigurationFacade.getInstance().getAuthenticationEndpointURL();
String fidp = request.getParameter(FrameworkConstants.RequestParams.FEDERATED_IDP);
Map<String, AuthenticatedIdPData> authenticatedIdPs = context.getCurrentAuthenticatedIdPs();
// NOTE : currentAuthenticatedIdPs (if not null) always contains the previousAuthenticatedIdPs
if (MapUtils.isEmpty(authenticatedIdPs)) {
if (LOG.isDebugEnabled()) {
LOG.debug("No current authenticated IDPs in the authentication context. " + "Continuing with the previous authenticated IDPs");
}
authenticatedIdPs = context.getPreviousAuthenticatedIdPs();
}
if (LOG.isDebugEnabled()) {
if (MapUtils.isEmpty(authenticatedIdPs)) {
LOG.debug("No previous authenticated IDPs found in the authentication context.");
} else {
LOG.debug(String.format("Found authenticated IdPs. Count: %d", authenticatedIdPs.size()));
}
}
if (context.isPassiveAuthenticate() && MapUtils.isNotEmpty(context.getAuthenticatedIdPsOfApp())) {
authenticatedIdPs = context.getAuthenticatedIdPsOfApp();
}
Map<String, AuthenticatorConfig> authenticatedStepIdps = FrameworkUtils.getAuthenticatedStepIdPs(stepConfig, authenticatedIdPs);
// check passive authentication
if (context.isPassiveAuthenticate()) {
if (authenticatedStepIdps.isEmpty()) {
context.setRequestAuthenticated(false);
} else {
String authenticatedIdP = authenticatedStepIdps.entrySet().iterator().next().getKey();
AuthenticatedIdPData authenticatedIdPData = authenticatedIdPs.get(authenticatedIdP);
populateStepConfigWithAuthenticationDetails(stepConfig, authenticatedIdPData, authenticatedStepIdps.get(authenticatedIdP));
request.setAttribute(FrameworkConstants.RequestParams.FLOW_STATUS, AuthenticatorFlowStatus.SUCCESS_COMPLETED);
}
stepConfig.setCompleted(true);
return;
} else {
long authTime = 0;
String maxAgeParam = request.getParameter(FrameworkConstants.RequestParams.MAX_AGE);
if (StringUtils.isNotBlank(maxAgeParam) && StringUtils.isNotBlank(context.getSessionIdentifier())) {
String loginTenantDomain = context.getLoginTenantDomain();
long maxAge = Long.parseLong((maxAgeParam));
if (FrameworkUtils.getSessionContextFromCache(context.getSessionIdentifier(), loginTenantDomain).getProperty(FrameworkConstants.UPDATED_TIMESTAMP) != null) {
authTime = Long.parseLong(FrameworkUtils.getSessionContextFromCache(context.getSessionIdentifier(), loginTenantDomain).getProperty(FrameworkConstants.UPDATED_TIMESTAMP).toString());
} else {
authTime = Long.parseLong(FrameworkUtils.getSessionContextFromCache(context.getSessionIdentifier(), loginTenantDomain).getProperty(FrameworkConstants.CREATED_TIMESTAMP).toString());
}
long currentTime = System.currentTimeMillis();
if (maxAge < (currentTime - authTime) / 1000) {
context.setForceAuthenticate(true);
} else {
context.setPreviousAuthTime(true);
}
}
}
if (request.getParameter(FrameworkConstants.RequestParams.USER_ABORT) != null && Boolean.parseBoolean(request.getParameter(FrameworkConstants.RequestParams.USER_ABORT))) {
request.setAttribute(FrameworkConstants.RequestParams.FLOW_STATUS, AuthenticatorFlowStatus.USER_ABORT);
stepConfig.setCompleted(true);
return;
}
// if Request has fidp param and if this is the first step
if (fidp != null && stepConfig.getOrder() == 1) {
handleHomeRealmDiscovery(request, response, context);
return;
} else if (context.isReturning()) {
// if this is a request from the multi-option page
if (request.getParameter(FrameworkConstants.RequestParams.AUTHENTICATOR) != null && !request.getParameter(FrameworkConstants.RequestParams.AUTHENTICATOR).isEmpty()) {
handleRequestFromLoginPage(request, response, context);
return;
} else {
// if this is a response from external parties (e.g. federated IdPs)
handleResponse(request, response, context);
return;
}
} else if (ConfigurationFacade.getInstance().isDumbMode() && authenticatedIdPs.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing in Dumb mode");
}
try {
request.setAttribute(FrameworkConstants.RequestParams.FLOW_STATUS, AuthenticatorFlowStatus.INCOMPLETE);
response.sendRedirect(loginPage + ("?" + context.getContextIdIncludedQueryParams()) + "&authenticators=" + URLEncoder.encode(authenticatorNames, "UTF-8") + "&hrd=true");
} catch (IOException e) {
throw new FrameworkException(e.getMessage(), e);
}
} else {
if (!(context.isForceAuthenticate() || stepConfig.isForced()) && !authenticatedStepIdps.isEmpty()) {
Map.Entry<String, AuthenticatorConfig> entry = authenticatedStepIdps.entrySet().iterator().next();
String idp = entry.getKey();
AuthenticatorConfig authenticatorConfig = entry.getValue();
if (context.isReAuthenticate()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Re-authenticating with " + idp + " IdP");
}
try {
context.setExternalIdP(ConfigurationFacade.getInstance().getIdPConfigByName(idp, context.getTenantDomain()));
} catch (IdentityProviderManagementException e) {
LOG.error("Exception while getting IdP by name", e);
}
doAuthentication(request, response, context, authenticatorConfig);
return;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Already authenticated. Skipping the step");
}
// skip the step if this is a normal request
AuthenticatedIdPData authenticatedIdPData = authenticatedIdPs.get(idp);
populateStepConfigWithAuthenticationDetails(stepConfig, authenticatedIdPData, authenticatedStepIdps.get(idp));
context.getCurrentAuthenticatedIdPs().put(idp, authenticatedIdPData);
stepConfig.setCompleted(true);
request.setAttribute(FrameworkConstants.RequestParams.FLOW_STATUS, AuthenticatorFlowStatus.SUCCESS_COMPLETED);
return;
}
} else {
// Find if step contains only a single authenticator with a single
// IdP. If yes, don't send to the multi-option page. Call directly.
boolean sendToPage = false;
boolean isAuthFlowHandlerOrBasicAuthInMultiOptionStep = false;
AuthenticatorConfig authenticatorConfig = null;
// Are there multiple authenticators?
if (authConfigList.size() > 1) {
sendToPage = true;
// redirecting to the multi option page.
for (AuthenticatorConfig config : authConfigList) {
if ((config.getApplicationAuthenticator() instanceof AuthenticationFlowHandler) || (config.getApplicationAuthenticator() instanceof LocalApplicationAuthenticator && (BASIC_AUTH_MECHANISM).equalsIgnoreCase(config.getApplicationAuthenticator().getAuthMechanism()))) {
authenticatorConfig = config;
isAuthFlowHandlerOrBasicAuthInMultiOptionStep = true;
sendToPage = false;
break;
}
}
} else {
// Are there multiple IdPs in the single authenticator?
authenticatorConfig = authConfigList.get(0);
if (authenticatorConfig.getIdpNames().size() > 1) {
sendToPage = true;
}
}
if (!sendToPage) {
// call directly
if (!authenticatorConfig.getIdpNames().isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Step contains only a single IdP. Going to call it directly");
}
// set the IdP to be called in the context
try {
context.setExternalIdP(ConfigurationFacade.getInstance().getIdPConfigByName(authenticatorConfig.getIdpNames().get(0), context.getTenantDomain()));
} catch (IdentityProviderManagementException e) {
LOG.error("Exception while getting IdP by name", e);
}
}
doAuthentication(request, response, context, authenticatorConfig);
/* If an authentication flow handler is redirected with incomplete status,
it will redirect to multi option page, as multi-option is available */
if ((request.getAttribute(FrameworkConstants.RequestParams.FLOW_STATUS)) == AuthenticatorFlowStatus.INCOMPLETE && isAuthFlowHandlerOrBasicAuthInMultiOptionStep) {
sendToMultiOptionPage(stepConfig, request, context, response, authenticatorNames);
}
return;
} else {
// else send to the multi option page.
sendToMultiOptionPage(stepConfig, request, context, response, authenticatorNames);
return;
}
}
}
}
use of org.wso2.carbon.identity.application.authentication.framework.AuthenticationFlowHandler in project carbon-identity-framework by wso2.
the class DefaultStepBasedSequenceHandler method handlePostAuthentication.
@SuppressWarnings("unchecked")
protected void handlePostAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws FrameworkException {
if (log.isDebugEnabled()) {
log.debug("Handling Post Authentication tasks");
}
SequenceConfig sequenceConfig = context.getSequenceConfig();
StringBuilder jsonBuilder = new StringBuilder();
boolean subjectFoundInStep = false;
boolean subjectAttributesFoundInStep = false;
int stepCount = 1;
Map<String, String> mappedAttrs = new HashMap<>();
Map<ClaimMapping, String> authenticatedUserAttributes = new HashMap<>();
boolean isAuthenticatorExecuted = false;
for (Map.Entry<Integer, StepConfig> entry : sequenceConfig.getStepMap().entrySet()) {
StepConfig stepConfig = entry.getValue();
AuthenticatorConfig authenticatorConfig = stepConfig.getAuthenticatedAutenticator();
if (authenticatorConfig == null) {
// ex: Different authentication sequences evaluated by the script
continue;
}
ApplicationAuthenticator authenticator = authenticatorConfig.getApplicationAuthenticator();
if (!(authenticator instanceof AuthenticationFlowHandler)) {
isAuthenticatorExecuted = true;
}
// build the authenticated idps JWT to send to the calling servlet.
if (stepCount == 1) {
jsonBuilder.append("\"idps\":");
jsonBuilder.append("[");
}
// build the JSON object for this step
jsonBuilder.append("{");
jsonBuilder.append("\"idp\":\"").append(stepConfig.getAuthenticatedIdP()).append("\",");
jsonBuilder.append("\"authenticator\":\"").append(authenticator.getName()).append("\"");
if (stepCount != sequenceConfig.getStepMap().size()) {
jsonBuilder.append("},");
} else {
// wrap up the JSON object
jsonBuilder.append("}");
jsonBuilder.append("]");
sequenceConfig.setAuthenticatedIdPs(IdentityApplicationManagementUtil.getSignedJWT(jsonBuilder.toString(), sequenceConfig.getApplicationConfig().getServiceProvider()));
stepConfig.setSubjectIdentifierStep(!subjectFoundInStep);
stepConfig.setSubjectAttributeStep(!subjectAttributesFoundInStep);
}
stepCount++;
if (authenticator instanceof FederatedApplicationAuthenticator) {
ExternalIdPConfig externalIdPConfig = null;
try {
externalIdPConfig = ConfigurationFacade.getInstance().getIdPConfigByName(stepConfig.getAuthenticatedIdP(), context.getTenantDomain());
} catch (IdentityProviderManagementException e) {
log.error("Exception while getting IdP by name", e);
}
context.setExternalIdP(externalIdPConfig);
String originalExternalIdpSubjectValueForThisStep = stepConfig.getAuthenticatedUser().getAuthenticatedSubjectIdentifier();
if (externalIdPConfig == null) {
String errorMsg = "An External IdP cannot be null for a FederatedApplicationAuthenticator";
log.error(errorMsg);
throw new FrameworkException(errorMsg);
}
Map<ClaimMapping, String> extAttrs;
Map<String, String> extAttibutesValueMap;
Map<String, String> localClaimValues = null;
Map<String, String> idpClaimValues = null;
extAttrs = stepConfig.getAuthenticatedUser().getUserAttributes();
extAttibutesValueMap = FrameworkUtils.getClaimMappings(extAttrs, false);
if (stepConfig.isSubjectAttributeStep()) {
subjectAttributesFoundInStep = true;
String idpRoleClaimUri = getIdpRoleClaimUri(stepConfig, context);
// Get the mapped user roles according to the mapping in the IDP configuration.
// Include the unmapped roles as it is.
List<String> identityProviderMappedUserRolesUnmappedInclusive = getIdentityProvideMappedUserRoles(externalIdPConfig, extAttibutesValueMap, idpRoleClaimUri, returnOnlyMappedLocalRoles);
String serviceProviderMappedUserRoles = getServiceProviderMappedUserRoles(sequenceConfig, identityProviderMappedUserRolesUnmappedInclusive);
if (StringUtils.isNotBlank(idpRoleClaimUri) && StringUtils.isNotBlank(serviceProviderMappedUserRoles)) {
extAttibutesValueMap.put(idpRoleClaimUri, serviceProviderMappedUserRoles);
}
if (mappedAttrs == null || mappedAttrs.isEmpty()) {
// do claim handling
mappedAttrs = handleClaimMappings(stepConfig, context, extAttibutesValueMap, true);
// external claim values mapped to local claim uris.
localClaimValues = (Map<String, String>) context.getProperty(FrameworkConstants.UNFILTERED_LOCAL_CLAIM_VALUES);
idpClaimValues = (Map<String, String>) context.getProperty(FrameworkConstants.UNFILTERED_IDP_CLAIM_VALUES);
}
}
if (stepConfig.isSubjectIdentifierStep()) {
if (!stepConfig.isSubjectAttributeStep()) {
/*
Do claim mapping inorder to get subject claim uri requested. This is done only if the
step is not a subject attribute step. Because it is already done in the previous flow if
the step is a subject attribute step.
*/
handleClaimMappings(stepConfig, context, extAttibutesValueMap, true);
}
subjectFoundInStep = true;
sequenceConfig.setAuthenticatedUser(new AuthenticatedUser(stepConfig.getAuthenticatedUser()));
}
if (stepConfig.isSubjectAttributeStep()) {
if (!sequenceConfig.getApplicationConfig().isMappedSubjectIDSelected()) {
// if we found the mapped subject - then we do not need to worry about
// finding attributes.
// if no requested claims are selected and sp claim dialect is not a standard dialect,
// send all local mapped claim values or idp claim values
ApplicationConfig appConfig = context.getSequenceConfig().getApplicationConfig();
if (MapUtils.isEmpty(appConfig.getRequestedClaimMappings()) && !isSPStandardClaimDialect(context.getRequestType())) {
if (MapUtils.isNotEmpty(localClaimValues)) {
mappedAttrs = localClaimValues;
} else if (MapUtils.isNotEmpty(idpClaimValues)) {
mappedAttrs = idpClaimValues;
}
}
authenticatedUserAttributes = FrameworkUtils.buildClaimMappings(mappedAttrs);
}
}
} else {
if (stepConfig.isSubjectIdentifierStep()) {
if (!stepConfig.isSubjectAttributeStep()) {
/*
Do claim mapping inorder to get subject claim uri requested. This is done only if the
step is not a subject attribute step. Because it is already done in the previous flow if
the step is a subject attribute step.
*/
handleClaimMappings(stepConfig, context, null, false);
}
subjectFoundInStep = true;
sequenceConfig.setAuthenticatedUser(new AuthenticatedUser(stepConfig.getAuthenticatedUser()));
if (log.isDebugEnabled()) {
log.debug("Authenticated User: " + sequenceConfig.getAuthenticatedUser().getLoggableUserId());
log.debug("Authenticated User Tenant Domain: " + sequenceConfig.getAuthenticatedUser().getTenantDomain());
}
}
if (stepConfig.isSubjectAttributeStep()) {
subjectAttributesFoundInStep = true;
// local authentications
mappedAttrs = handleClaimMappings(stepConfig, context, null, false);
handleRoleMapping(context, sequenceConfig, mappedAttrs);
authenticatedUserAttributes = FrameworkUtils.buildClaimMappings(mappedAttrs);
}
}
}
if (!isAuthenticatorExecuted) {
String errorMsg = String.format("No authenticator have been executed in the authentication flow of " + "application: %s in tenant-domain: %s", sequenceConfig.getApplicationConfig().getApplicationName(), context.getTenantDomain());
log.error(errorMsg);
throw new MisconfigurationException(errorMsg);
}
if (isSPStandardClaimDialect(context.getRequestType()) && authenticatedUserAttributes.isEmpty() && sequenceConfig.getAuthenticatedUser() != null) {
sequenceConfig.getAuthenticatedUser().setUserAttributes(authenticatedUserAttributes);
}
if (!authenticatedUserAttributes.isEmpty() && sequenceConfig.getAuthenticatedUser() != null) {
sequenceConfig.getAuthenticatedUser().setUserAttributes(authenticatedUserAttributes);
}
}
Aggregations