WebLogic的JAAS配置

时间:2016-11-03 08:05:25

标签: java weblogic12c jaas

我启动了我的Web应用程序并在tomcat中运行。现在,我必须在WebLogic 12c中运行我的应用程序(war文件)。

我找不到足够的信息:

1)weblogic.xml是否必须与war文件中的web.xml一起使用?教程提到了在weblogic.xml中设置上下文和一些更多的配置,但没有我可以弄清楚它是强制性的。

2)我需要在WebLogic中配置JAAS领域。我尝试配置领域,但不知道有什么东西与配置搞混。有人可以指向我正确的教程或提供JAAS设置所需的步骤。

我在startWebLogic.cmd文件中添加了 -Djava.security.auth.login.config =%DOMAIN_HOME%\ jaas.config

以下是我的登录模块代码:

public class AuthLoginModule implements LoginModule {
    private static Logger logger = Logger.getLogger(AuthLoginModule.class);
    // initial state
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map<String, ?> sharedState;
    private Map<String, ?> options;
    // the authentication status
    private boolean succeeded = false;
    private boolean commitSucceeded = false;

    // username and password
    private String username;
    private String password;
    Map<String,String> userData = new HashMap<String,String>();

    private AuthPrincipal userPrincipal;

    public AuthLoginModule() throws WebAuthServiceException {
        super();
    }

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.setSharedState(sharedState);
        this.setOptions(options);
        String appName = options.get(WebAuthConstants.APP_UNIQUE_NAME).toString();
        logger.info("AppName in AuthLoginModule: " + appName);
    }

    public boolean login() throws LoginException {
        if (callbackHandler == null)
            throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user");

        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("user name: ");
        callbacks[1] = new PasswordCallback("password: ", false);
        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
            if (tmpPassword == null) {
                // treat a NULL password as an empty password
                tmpPassword = new char[0];
            }
            password = new String(tmpPassword);
            if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
                throw new LoginException("User name or password is empty");
            }

        } catch (java.io.IOException ioe) {
            throw new LoginException(ioe.toString());
        } catch (UnsupportedCallbackException uce) {
            throw new LoginException("Error: " + uce.getCallback().toString() + " not available to garner authentication information " + "from the user");
        }
        String validateUserCredData = validateUserCred();
        if (validateUserCredData!=null) {
            if(JsonUtil.jsonFromString(validateUserCredData).get("statusCode").getAsInt()== HttpStatus.SC_UNAUTHORIZED) {
                userData.put(DataConstants._USER_PWD_STATUS, DataConstants._RESET_USER_PWD);
            }
            succeeded = true;
        } else {
            succeeded = false;
        }
        return succeeded;
    }


    private String validateUserCred() {
        try {
            logger.info("Started validating user credentials for: " + username);
            // If there is no error then user allowed to access all
            UserClientService UserClientService = ClientServiceFactory.getInstance().getUserService();
            return UserClientService.validateUserCredentials(username, password);
        } catch (Throwable e) {
            logger.error("Exception while authentication user against Service API, Error Code: ", e);
        }
        return null;
    }

    public boolean commit() throws LoginException {
        if (succeeded == false) {
            return false;
        } else {
            // add a Principal (authenticated identity) to the Subject
            // assume the user we authenticated is the SamplePrincipal
            userPrincipal = new AuthPrincipal(username, password, userData);
            if (!subject.getPrincipals().contains(userPrincipal))
                subject.getPrincipals().add(userPrincipal);
            logger.info("Login Module successfully added user principal");
            // in any case, clean out state
            username = null;
            password = null;
            commitSucceeded = true;
            return true;
        }
    }

    public boolean abort() throws LoginException {
        if (succeeded == false) {
            return false;
        } else if (succeeded == true && commitSucceeded == false) {
            // login succeeded but overall authentication failed
            succeeded = false;
            username = null;
            password = null;
            userPrincipal = null;
        } else {
            // overall authentication succeeded and commit succeeded,
            // but someone else's commit failed
            logout();
        }
        return true;
    }

    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(userPrincipal);
        succeeded = false;
        succeeded = commitSucceeded;
        username = null;
        password = null;
        userPrincipal = null;
        logger.info("Login Module successfully removed user principal after successful logout");
        return true;
    }

    public Map<String, ?> getSharedState() {
        return sharedState;
    }

    public void setSharedState(Map<String, ?> sharedState) {
        this.sharedState = sharedState;
    }

    public Map<String, ?> getOptions() {
        return options;
    }

    public void setOptions(Map<String, ?> options) {
        this.options = options;
    }
}

在一些教程中,我可以看到,LoginModule是专门针对WebLogic编写的,但我觉得LoginModule不应该因为它遵循J2EE而改变任何服务器。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

最后,我将基于表单的JAAS配置按照我的需要工作。 我在评论部分和一些博客中也遵循了KC Wong提供的oracle docs链接。

以下是我遵循的步骤。

1)首先,我需要创建一个自定义身份验证提供程序。我创建了一个Java项目,其中包括我的 LoginModule,AuthenticationProviderImpl (实现 AuthenticationProviderV2 )和MBean XML。 此MBean XML包含有关MBeanType和MBeanAttribute的信息。 我在下面发布了一些重要文件以获取更多信息。

WLAuthenticationProviderImpl .java

package com.abc.wls.security.providers.authentication;

import java.util.HashMap;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;

import weblogic.management.security.ProviderMBean;
import weblogic.security.provider.PrincipalValidatorImpl;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;

public class WLAuthenticationProviderImpl implements AuthenticationProviderV2 {
    private String description = "MyOwn WLAuthentication Provider";
    // private SimpleSampleAuthenticatorDatabase database;
    private LoginModuleControlFlag controlFlag;

    public void initialize(ProviderMBean mbean, SecurityServices services) {
        System.out.println("WLAuthenticationProviderImpl.initialize");
        // WLAuthenticationProviderMBean mbean =
        // (WLAuthenticationProviderMBean) mbean;

        // SimpleSampleAuthenticatorMBean myMBean =
        // (SimpleSampleAuthenticatorMBean) mbean;
        // description = myMBean.getDescription() + "\n" + myMBean.getVersion();
        // database = new SimpleSampleAuthenticatorDatabase(myMBean);
        // String flag = myMBean.getControlFlag();
        /*
         * if (flag.equalsIgnoreCase("REQUIRED")) { controlFlag =
         * LoginModuleControlFlag.REQUIRED; } else if
         * (flag.equalsIgnoreCase("OPTIONAL")) { controlFlag =
         * LoginModuleControlFlag.OPTIONAL; } else if
         * (flag.equalsIgnoreCase("REQUISITE")) { controlFlag =
         * LoginModuleControlFlag.REQUISITE; } else if
         * (flag.equalsIgnoreCase("SUFFICIENT")) { controlFlag =
         * LoginModuleControlFlag.SUFFICIENT; } else { throw new
         * IllegalArgumentException("invalid flag value" + flag); }
         */
    }

    public String getDescription() {
        System.out.println("WLAuthenticationProviderImpl.getDescription");
        return description;
    }

    public void shutdown() {
        System.out.println("WLSecurityProviderImpl.shutdown");
    }

    private AppConfigurationEntry getConfiguration(HashMap options) {
        System.out.println("WLAuthenticationProviderImpl.getConfiguration");
        if (options == null)
            options = new HashMap<>();
        options.put("app-unique-name", "xyz-ui");
        // return new
        // AppConfigurationEntry("examples.security.providers.authentication.Simple.Simple.SampleLoginModuleImpl",
        // controlFlag, options);
        return new AppConfigurationEntry("com.abc.wls.security.providers.authentication.WLServerLoginModule", LoginModuleControlFlag.REQUIRED, options);
    }

    public AppConfigurationEntry getLoginModuleConfiguration() {
        System.out.println("WLAuthenticationProviderImpl.getLoginModuleConfiguration");
        HashMap options = new HashMap();
        return getConfiguration(options);
    }

    public AppConfigurationEntry getAssertionModuleConfiguration() {
        System.out.println("WLAuthenticationProviderImpl.getAssertionModuleConfiguration");
        HashMap options = new HashMap();
        options.put("IdentityAssertion", "true");
        return getConfiguration(options);
    }

    public PrincipalValidator getPrincipalValidator() {
        return new PrincipalValidatorImpl();
    }

    public IdentityAsserterV2 getIdentityAsserter() {
        return null;
    }

}

<强> WLServerLoginModule.java

package com.abc.wls.security.providers.authentication;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import weblogic.logging.NonCatalogLogger;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class WLServerLoginModule implements LoginModule {
    private static NonCatalogLogger logger = new NonCatalogLogger("WLServerLoginModule");
    // initial state
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map<String, ?> sharedState;
    private Map<String, ?> options;
    // the authentication status
    private boolean succeeded = false;
    private boolean commitSucceeded = false;

    // username and password
    private String username;
    private String password;
    Map<String, String> userData = new HashMap<String, String>();
    private final JsonParser jsonParser = new JsonParser();

    private WLSAuthPrincipal userPrincipal;

    public WLServerLoginModule() throws LoginException {
        super();
    }

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
        logger.info("WLServerLoginModule.initialize");
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.setSharedState(sharedState);
        this.setOptions(options);
        String appName = options.get("app-unique-name").toString();
        logger.info("AppName in WLServerLoginModule: " + appName);
    }

    public boolean login() throws LoginException {
        logger.info("WLServerLoginModule.login");
        if (callbackHandler == null)
            throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user");

        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("user name: ");
        callbacks[1] = new PasswordCallback("password: ", false);
        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
            if (tmpPassword == null) {
                // treat a NULL password as an empty password
                tmpPassword = new char[0];
            }
            password = new String(tmpPassword);
            if (isEmpty(username) || isEmpty(password)) {
                throw new LoginException("User name or password is empty");
            }
        } catch (java.io.IOException ioe) {
            throw new LoginException(ioe.toString());
        } catch (UnsupportedCallbackException uce) {
            throw new LoginException("Error: " + uce.getCallback().toString() + " not available to garner authentication information " + "from the user");
        }

        try {
            if (isValidUser(username, password)) {
                succeeded = true;
            } else {
                succeeded = false;
            }
        } catch (Exception e) {
            logger.error("Post validation exception e: ", e);
            succeeded = false;
        }
        return succeeded;
    }

    private boolean isValidUser(String username, String password) {
        // Your custom validation logic
        return true;
    }


    public boolean commit() throws LoginException {
        logger.info("WLServerLoginModule.commit");
        if (succeeded == false) {
            return false;
        } else {
            // add a Principal (authenticated identity) to the Subject
            // assume the user we authenticated is the SamplePrincipal
            userPrincipal = new WLSAuthPrincipal(username, password, userData);
            if (!subject.getPrincipals().contains(userPrincipal)) {
                // subject.getPrincipals().add(new WLSUserImpl(username));
                subject.getPrincipals().add(userPrincipal);
                logger.info("Custom User principal Added");
            }
            subject.getPrincipals().add(new WLSUserImpl(username));
            subject.getPrincipals().add(new WLSGroupImpl("ABC_USERS"));
            logger.info("Login Module successfully added user principal");
            if (subject != null && subject.getPrincipals() != null) {
                logger.info("All user principals added: " + subject.getPrincipals());
                logger.info("All user principals count: " + subject.getPrincipals().size());
            }
            // in any case, clean out state
            username = null;
            password = null;
            commitSucceeded = true;
            return true;
        }
    }

    public boolean abort() throws LoginException {
        logger.info("WLServerLoginModule.abort");
        if (succeeded == false) {
            return false;
        } else if (succeeded == true && commitSucceeded == false) {
            // login succeeded but overall authentication failed
            succeeded = false;
            username = null;
            password = null;
            userPrincipal = null;
        } else {
            // overall authentication succeeded and commit succeeded, but
            // someone else's commit failed
            logout();
        }
        return true;
    }

    public boolean logout() throws LoginException {
        logger.info("WLServerLoginModule.logout");
        subject.getPrincipals().remove(userPrincipal);
        succeeded = false;
        succeeded = commitSucceeded;
        username = null;
        password = null;
        userPrincipal = null;
        logger.info("Login Module successfully removed user principal after successful logout");
        return true;
    }

    public Map<String, ?> getSharedState() {
        return sharedState;
    }

    public void setSharedState(Map<String, ?> sharedState) {
        this.sharedState = sharedState;
    }

    public Map<String, ?> getOptions() {
        return options;
    }

    public void setOptions(Map<String, ?> options) {
        this.options = options;
    }
}

2)我想拥有自己的Custom AuthPrincipal,扩展到 WLSAbstractPrincipal 并实现 WLUser 。我的情况略有不同,我想在AuthPrincipal中存储用户名,密码和一些关于用户的更重要信息。所以,我创建了这个Custom AuthPrincipal。

3)现在,创建一个build.xml,它将发出此自定义身份验证主体。

4)在生成jar之后,我将其复制到{WL_HOME} / server / lib / mbeantypes以及WebLogic支持的默认身份验证提供程序中。

5)现在,我们需要更改myrealm的默认领域。使用任何名称创建新的身份验证提供程序,并选择其类型作为您已创建的自定义身份验证提供程序的名称。并使这个Auth Provider成为必需的。