/* * Copyright (c) 2013, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.identity.application.authentication.framework; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.identity.application.authentication.framework.config.builder.FileBasedConfigurationBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException; import org.wso2.carbon.identity.application.authentication.framework.exception.LogoutFailedException; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.common.model.Property; import org.wso2.carbon.user.core.util.UserCoreUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This is the super class of all the Application Authenticators. Authenticator writers must extend * this. */ public abstract class AbstractApplicationAuthenticator implements ApplicationAuthenticator { private static final long serialVersionUID = -4406878411547612129L; private static final Log log = LogFactory.getLog(AbstractApplicationAuthenticator.class); @Override public AuthenticatorFlowStatus process(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException, LogoutFailedException { // if an authentication flow if (!context.isLogoutRequest()) { if (!canHandle(request) || (request.getAttribute(FrameworkConstants.REQ_ATTR_HANDLED) != null && ((Boolean) request .getAttribute(FrameworkConstants.REQ_ATTR_HANDLED)))) { initiateAuthenticationRequest(request, response, context); context.setCurrentAuthenticator(getName()); return AuthenticatorFlowStatus.INCOMPLETE; } else { try { processAuthenticationResponse(request, response, context); if (this instanceof LocalApplicationAuthenticator) { if (!context.getSequenceConfig().getApplicationConfig().isSaaSApp()) { String userDomain = context.getSubject().getTenantDomain(); String tenantDomain = context.getTenantDomain(); if (!StringUtils.equals(userDomain, tenantDomain)) { context.setProperty("UserTenantDomainMismatch", true); throw new AuthenticationFailedException("Service Provider tenant domain must be " + "equal to user tenant domain for non-SaaS applications"); } } } request.setAttribute(FrameworkConstants.REQ_ATTR_HANDLED, true); return AuthenticatorFlowStatus.SUCCESS_COMPLETED; } catch (AuthenticationFailedException e) { Map<Integer, StepConfig> stepMap = context.getSequenceConfig().getStepMap(); boolean stepHasMultiOption = false; if (stepMap != null && !stepMap.isEmpty()) { StepConfig stepConfig = stepMap.get(context.getCurrentStep()); if (stepConfig != null) { stepHasMultiOption = stepConfig.isMultiOption(); } } if (retryAuthenticationEnabled() && !stepHasMultiOption) { context.setRetrying(true); context.setCurrentAuthenticator(getName()); initiateAuthenticationRequest(request, response, context); return AuthenticatorFlowStatus.INCOMPLETE; } else { throw e; } } } // if a logout flow } else { try { if (!canHandle(request)) { context.setCurrentAuthenticator(getName()); initiateLogoutRequest(request, response, context); return AuthenticatorFlowStatus.INCOMPLETE; } else { processLogoutResponse(request, response, context); return AuthenticatorFlowStatus.SUCCESS_COMPLETED; } } catch (UnsupportedOperationException e) { if (log.isDebugEnabled()) { log.debug("Ignoring UnsupportedOperationException.", e); } return AuthenticatorFlowStatus.SUCCESS_COMPLETED; } } } protected void initiateAuthenticationRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException { } protected abstract void processAuthenticationResponse(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException; protected void initiateLogoutRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws LogoutFailedException { throw new UnsupportedOperationException(); } protected void processLogoutResponse(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws LogoutFailedException { throw new UnsupportedOperationException(); } protected AuthenticatorConfig getAuthenticatorConfig() { AuthenticatorConfig authConfig = FileBasedConfigurationBuilder.getInstance() .getAuthenticatorBean(getName()); if (authConfig == null) { authConfig = new AuthenticatorConfig(); authConfig.setParameterMap(new HashMap<String, String>()); } return authConfig; } protected boolean retryAuthenticationEnabled() { return false; } @Override public String getClaimDialectURI() { return null; } @Override public List<Property> getConfigurationProperties() { return new ArrayList<Property>(); } protected String getUserStoreAppendedName(String userName) { if (!userName.contains(CarbonConstants.DOMAIN_SEPARATOR) && UserCoreUtil.getDomainFromThreadLocal() != null && !"".equals(UserCoreUtil.getDomainFromThreadLocal())) { userName = UserCoreUtil.getDomainFromThreadLocal() + CarbonConstants.DOMAIN_SEPARATOR + userName; } return userName; } }