/* * 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.authenticator.requestpath.basicauth; import org.apache.axiom.om.util.Base64; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator; import org.wso2.carbon.identity.application.authentication.framework.RequestPathApplicationAuthenticator; 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.model.AuthenticatedUser; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.authenticator.requestpath.basicauth.internal.BasicAuthRequestPathAuthenticatorServiceComponent; import org.wso2.carbon.identity.base.IdentityRuntimeException; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.user.core.UserStoreManager; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; public class BasicAuthRequestPathAuthenticator extends AbstractApplicationAuthenticator implements RequestPathApplicationAuthenticator { private static final long serialVersionUID = -3707836631281782935L; private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; private static final String BASIC_AUTH_SCHEMA = "Basic"; private static final String AUTHENTICATOR_NAME = "BasicAuthRequestPathAuthenticator"; private static Log log = LogFactory.getLog(BasicAuthRequestPathAuthenticator.class); @Override public boolean canHandle(HttpServletRequest request) { if (log.isTraceEnabled()) { log.trace("Inside canHandle()"); } String headerValue = (String) request.getSession().getAttribute(AUTHORIZATION_HEADER_NAME); if (headerValue != null && !"".equals(headerValue.trim())) { String[] headerPart = headerValue.trim().split(" "); if (BASIC_AUTH_SCHEMA.equals(headerPart[0])) { return true; } } else if (request.getParameter("sectoken") != null) { return true; } return false; } @Override protected void processAuthenticationResponse(HttpServletRequest request, HttpServletResponse response, AuthenticationContext context) throws AuthenticationFailedException { // if this was set by the relevant servlet String headerValue = (String) request.getSession().getAttribute(AUTHORIZATION_HEADER_NAME); String credential = null; if (headerValue != null) { credential = headerValue.trim().split(" ")[1]; } else { credential = request.getParameter("sectoken"); } String credentials = new String(Base64.decode(credential)); String username = credentials.substring(0, credentials.indexOf(":")); String password = credentials.substring(credentials.indexOf(":") + 1); if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { throw new AuthenticationFailedException("username and password cannot be empty"); } try { int tenantId = IdentityTenantUtil.getTenantIdOfUser(username); UserStoreManager userStoreManager = (UserStoreManager) BasicAuthRequestPathAuthenticatorServiceComponent. getRealmService().getTenantUserRealm(tenantId).getUserStoreManager(); boolean isAuthenticated = userStoreManager.authenticate( MultitenantUtils.getTenantAwareUsername(username), password); if (!isAuthenticated) { throw new AuthenticationFailedException("Authentication Failed"); } if (log.isDebugEnabled()) { log.debug("Authenticated user " + username); } Map<String, Object> authProperties = context.getProperties(); String tenantDomain = MultitenantUtils.getTenantDomain(username); if (authProperties == null) { authProperties = new HashMap<String, Object>(); context.setProperties(authProperties); } // TODO: user tenant domain has to be an attribute in the // AuthenticationContext authProperties.put("user-tenant-domain", tenantDomain); context.setSubject(AuthenticatedUser.createLocalAuthenticatedUserFromSubjectIdentifier( FrameworkUtils.prependUserStoreDomainToName(username))); } catch (IdentityRuntimeException e) { if(log.isDebugEnabled()){ log.debug("BasicAuthentication failed while trying to get the tenant ID of the user " + username, e); } throw new AuthenticationFailedException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new AuthenticationFailedException("Authentication Failed"); } } @Override public String getContextIdentifier(HttpServletRequest request) { return null; } @Override public String getFriendlyName() { return "basic-auth"; } @Override public String getName() { return AUTHENTICATOR_NAME; } }