我启动了我的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而改变任何服务器。
任何帮助都将不胜感激。
答案 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成为必需的。