2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * The contents of this file are subject to the terms
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * of the Common Development and Distribution License
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * (the License). You may not use this file except in
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * compliance with the License.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * You can obtain a copy of the License at
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * See the License for the specific language governing
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * permission and limitations under the License.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * When distributing Covered Code, include this CDDL
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Header Notice in each file and include the License file
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * If applicable, add the following below the CDDL Header,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * with the fields enclosed by brackets [] replaced by
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * your own identifying information:
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * $Id: Application.java,v 1.9 2009/07/23 18:54:17 qcheng Exp $
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * Portions Copyrighted 2011-2016 ForgeRock AS.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterpackage com.sun.identity.authentication.modules.application;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpottsimport static com.sun.identity.authentication.util.ISAuthConstants.SPECIAL_USERS_CONTAINER;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpottsimport static com.sun.identity.sm.SMSEntry.getRootSuffix;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport javax.security.auth.callback.CallbackHandler;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport javax.security.auth.callback.NameCallback;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport javax.security.auth.callback.PasswordCallback;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport com.sun.identity.authentication.spi.AMLoginModule;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport com.sun.identity.authentication.spi.AuthLoginException;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport com.sun.identity.authentication.util.ISAuthConstants;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterimport com.sun.identity.idm.AMIdentityRepository;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpottsimport com.sun.identity.security.DecodeAction;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * Application login module. This is used to authenticate agents and users of ssoadm.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Use <code>IDToken0</code> to specify application name and
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * <code>IDToken1</code> to specify secret.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * (Old usage : <code>Login.Token0</code> to specify application name and
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * <code>Login.Token1</code> to specify secret.) For example:
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * "module=Application&IDToken0=UrlAccessAgent&IDToken1=secret"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * "module=Application&IDToken0=<user id for Agent>&IDToken1=
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * <password for Agent user>"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Old usage:
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * "module=Application&Login.Token0=UrlAccessAgent&Login.Token1=secret"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterpublic class Application extends AMLoginModule {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster private static final String amAuthApplication = "amAuthApplication";
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster private static Debug debug = Debug.getInstance(amAuthApplication);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts private static final DN SPECIAL_USERS_ROOT = DN.valueOf(SPECIAL_USERS_CONTAINER + "," + getRootSuffix());
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster debug.message("Application module getting secret");
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts String tmp = SystemProperties.get(Constants.AM_SERVICES_SECRET).trim();
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts secret = AccessController.doPrivileged(new DecodeAction(tmp));
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster public void init(Subject subject, Map sharedState, Map options) {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster bundle = amCache.getResBundle(amAuthApplication, locale);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("ApplicationAuth resbundle locale={}", locale);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.error("ApplicationAuthModule Init: {}", e.getMessage());
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster debug.message("Init : NULL secret in AMConfig.properties");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Implementation of <code>AMLoginModule</code> abstract method.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Refer to <code>AMLoginModule</code> for method syntax.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster public int process(Callback[] callbacks, int state)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster // check if there is any error during initialize
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster throw new AuthLoginException(amAuthApplication, errorMsg, null);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster HttpServletRequest req = getHttpServletRequest();
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster secretParam = req.getParameter("Login.Token1");
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts throw new AuthLoginException(amAuthApplication, "wrongSecret", null);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (secretParam == null || secretParam.length() == 0) {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster throw new AuthLoginException(amAuthApplication, "noPassword", null);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts if (secret != null && secret.length() != 0 && secretParam.equals(secret)) {
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("App.validate, secret matched for user : {}", userName);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (userName == null || userName.length() == 0) {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster // backward compatible with the gateway for portal
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts newUserName = ISAuthConstants.APPLICATION_USER_PREFIX + "gateway";
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts newUserName = ISAuthConstants.APPLICATION_USER_PREFIX + userName;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster String userDNString = ISAuthConstants.APPLICATION_USER_NAMING_ATTR +
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts "=" + newUserName + "," + SPECIAL_USERS_CONTAINER + "," + getRootSuffix();
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("{} is not a valid special user entry", userDNString);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.error("App validation failed, User not Valid: {}", userName);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts throw new AuthLoginException(amAuthApplication, "userInvalid", null);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster } else if (!doFallbackAuth(userName, secretParam)) {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster debug.error("App validation failed, User not Valid: " + userName);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts throw new AuthLoginException(amAuthApplication, "userInvalid", null);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster private boolean doFallbackAuth(String userName, String userPassword)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster boolean success = false;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("doFallbackAuth : User = {}", userName);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (userName != null && (userName.length() != 0)) {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (authenticateToDatastore(userName, userPassword)) {
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("Application.doFallbackAuth: Authenticated to AgentsRepo.");
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * Authenticates to the datastore using idRepo API
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * @param userName User Name
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * @param userPassword User Password
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * @return <code>true</code> if success. <code>false</code> if failure
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts * @throws AuthLoginException
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts private boolean authenticateToDatastore(String userName, String userPassword) throws AuthLoginException {
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts boolean retval = false;
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts NameCallback nameCallback = new NameCallback("NamePrompt");
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts PasswordCallback passwordCallback = new PasswordCallback("PasswordPrompt",false);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts passwordCallback.setPassword(userPassword.toCharArray());
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts AMIdentityRepository idrepo = getAMIdentityRepository(getRequestOrg());
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts retval = idrepo.authenticate(IdType.AGENT, callbacks);
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("Application.authenticateToDatastore: IdRepo Exception", idrepoExp);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Returns Principal for the authenticated user.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @return Principal for the authenticated user or null if
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * authentication did not succeed.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster public java.security.Principal getPrincipal() {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster userPrincipal = new ApplicationPrincipal(userTokenId);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Sends callbacks to get appname and/or secret
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @return Map contains appname and/or secret, key "uid" corresponding
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * to appname, key "secret" corresponds to secret
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster CallbackHandler callbackHandler = getCallbackHandler();
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster throw new AuthLoginException(amAuthApplication,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster callbacks[0] = new NameCallback(bundle.getString("appname"));
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.message("Callback is.. : {}", callbacks);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster // map to hold return
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster // process return
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster char[] pass = ((PasswordCallback) cb).getPassword();
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster String username = ((NameCallback) cb).getName();
c9ba1a8f3afcf43e26fe5b062ac652b347b283fbJames Phillpotts debug.error("sendCallback: {}", e.getMessage());