我们有一个用例,其中在 JBoss 5.1 上运行的 Web 应用程序(例如应用程序 A)需要以编程方式登录到另一个应用程序(例如应用程序 B)。应用程序 B 使用 Kerbros 作为其身份验证机制。
- 我们首先创建了一个能够使用 JAAS 和 Java GSS-API 成功登录到应用程序 B 的独立客户端。所以这行得通。
- 接下来,我们创建了一个非常简单的 HelloWorld Like Web 应用程序,只有一个 servlet。在这个 servlet 的 doGet 方法中,我们合并了与我们在 #1 中创建的独立客户端相同的代码,并将其部署到全新安装的 JBoss 5.1。当调用这个 servlet 时,我们会看到下面内联的异常。
- 部署到 Weblogic 10.x 时,相同的 servlet Web 应用程序无需任何更改即可正常工作。
我们在这里缺少什么?org.jboss.security.auth.spi.*
我的预感是 JBoss 有一个安全 API(那么我们如何告诉 JBoss 不要使用它自己的实现呢?需要做什么才能在 JBoss 5.1 中完成这项工作?
我在下面的测试 servlet 中列出了整个代码。如果需要任何进一步的信息,请告诉我,我很乐意提供。
代码:
package test;
import java.io.BufferedWriter;
import java.io.IOException;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Date;
import java.util.Properties;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.oozie.client.AuthOozieClient;
import org.apache.oozie.client.OozieClientException;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
private Oid KERB_V5_OID;
private Oid KRB5_PRINCIPAL_NAME_OID ;
private Properties hdfsProperties = new Properties();
private Properties jobProperties = new Properties();
private String userId = "xyxyxyxy";
private String pw = "abcabcabc";
/**
* @see HttpServlet#HttpServlet()
*/
public HelloWorld() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedWriter writer = new BufferedWriter(response.getWriter());
writer.write("Hello");
loadProperties();
createOid();
Subject subject = new Subject();
LoginContext lc = login(subject);
Principal userPrincipal = createUserPrincipal(subject);
try {
submitOozieWorkflow(lc, userPrincipal);
} catch (LoginException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
writer.flush();
writer.close();
}
public LoginContext login(Subject subject) {
String realm = hdfsProperties.getProperty("kerberos.realm");
String kdc = hdfsProperties.getProperty("kerberos.kdc");
System.setProperty("java.security.krb5.realm", realm);
System.setProperty("java.security.krb5.kdc", kdc);
System.setProperty("java.security.auth.login.config",hdfsProperties.getProperty("jaas.conf"));
LoginContext lc = null;
try {
lc = new LoginContext("Krb5LoginContext", subject);
lc.login(); // **<----Exception gets thrown here**
} catch (LoginException e) {
e.printStackTrace();
throw new java.lang.IllegalStateException(e);
}
return lc;
}
public void loadProperties(/*String command, Properties hiveProperties*/) {
hdfsProperties.put("jaas.conf", "C:/tmp/jaas.conf");
hdfsProperties.put("hadoop.service.account", "zzzzzzzzz");
hdfsProperties.put("kerberos.realm", "DEV.HDFS.COM");
hdfsProperties.put("kerberos.kdc", "lcdre30348.xxxxxxxxx.com:88");
hdfsProperties.put("kerberos.application.principal", "krbtgt/DEV.HDFS.COM@DEV.HDFS.COM");
// Job Properties
// standard
jobProperties.put("jobTracker", "lcdre30347.xyzyxzxyz.com:8021");
jobProperties.put("nameNode", "hdfs://lcdre30346.xyzyxzxyz.com:8020");
jobProperties.put("oozie_server", "http://lcdre30348.xyzyxzxyz.com:11000/oozie");
jobProperties.put("oozie.libpath", "/user/oozie/share/lib");
jobProperties.put("oozie.wf.application.path", "hdfs://lcdre30346.xyzyxzxyz.com:8020/user/nbsababab/oozie/apps/wf-sqoop/sqoop-import-wf.xml");
jobProperties.put("oozie.log", "/tmp/log/");
jobProperties.put("queueName", "ababab");
jobProperties.put("oozieRoot", "oozie");
jobProperties.put("oozie.use.system.libpath", "true");
// Sqoop Import cmd
jobProperties.put("sqoopImport", "import --connect jdbc:teradata://WDVTERA.xyzyxzxyz.com/database=TESTAB_D,TMODE=TERA,SESSIONS=10 --username "+userId+" --password "+pw+" --table TZ_APP_MAST --target-dir /user/nbsababab/mike/appmast2 -m 1");
//jobProperties.put("sqoopImport",command);
// Parameterized
jobProperties.put("script", "hive-create-external-table.hql");
jobProperties.put("databaseName", "TEST2");
jobProperties.put("tableName", "TZ_APP_MAST");
jobProperties.put("columns", "APP_ID int,APP_NM string,APP_ABBREV_TXT string,APP_TYP_CD int,APP_STAT_CD int,SEC_FLAG_ID int");
jobProperties.put("delimiter", ",");
jobProperties.put("location", "/user/nbsababab/mike/appmast2");
}
public void createOid() {
try {
KERB_V5_OID = new Oid("1.2.840.113554.1.2.2");
KRB5_PRINCIPAL_NAME_OID = new Oid("1.2.840.113554.1.2.2.1");
} catch (final GSSException ex) {
throw new Error(ex);
}
}
public Principal createUserPrincipal(Subject subject) {
Set<Principal> principalSet = subject.getPrincipals();
if (principalSet.size() != 1) {
throw new AssertionError("No or several principals: "+ principalSet);
}
Principal userPrincipal = principalSet.iterator().next();
System.out.println(userPrincipal.toString());
return userPrincipal;
}
private void submitOozieWorkflow(LoginContext lc, Principal userPrincipal) throws LoginException {
String jobId = null;
final String userPrincipalName = userPrincipal.getName();
jobId = Subject.doAsPrivileged(lc.getSubject(),
new PrivilegedAction<String>() {
public String run() {
// This is where all secure transaction happen.
try {
final GSSManager manager = GSSManager.getInstance();
GSSName clientName = manager.createName(userPrincipalName, KRB5_PRINCIPAL_NAME_OID);
final GSSCredential clientCred = manager.createCredential(clientName, 8 * 3600,
KERB_V5_OID,
GSSCredential.INITIATE_ONLY);
final GSSName serverName = manager.createName(
hdfsProperties.getProperty("kerberos.application.principal"),
KRB5_PRINCIPAL_NAME_OID);
final GSSContext context = manager.createContext(serverName, KERB_V5_OID, clientCred, GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true);
context.requestConf(false);
context.requestInteg(true);
AuthOozieClient wc = new AuthOozieClient(jobProperties.getProperty("oozie_server"));
Properties conf = wc.createConfiguration();
for (String key : jobProperties.stringPropertyNames()) {
String value = jobProperties.getProperty(key);
System.out.println(key + " => " + value);
conf.setProperty(key,jobProperties.getProperty(key));
}
System.out.println("Workflow job about to submit");
return wc.run(conf);
} catch (GSSException e) {
e.printStackTrace();
return null;
} catch (OozieClientException e) {
e.printStackTrace();
}
return null;
}
}// Privillaged action implementation ends here..
, null);
System.out.println("jobId:"+jobId);
lc.logout();
System.out.println(new Date());
}
}
堆栈跟踪:
11:05:25,749 ERROR [UsersRolesLoginModule] Failed to load users/passwords/role files
java.io.IOException: No properties file: users.properties or defaults: defaultUsers.properties found
at org.jboss.security.auth.spi.Util.loadProperties(Util.java:198)
at org.jboss.security.auth.spi.UsersRolesLoginModule.loadUsers(UsersRolesLoginModule.java:186)
at org.jboss.security.auth.spi.UsersRolesLoginModule.createUsers(UsersRolesLoginModule.java:200)
at org.jboss.security.auth.spi.UsersRolesLoginModule.initialize(UsersRolesLoginModule.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.invoke(Unknown Source)
at javax.security.auth.login.LoginContext.access$000(Unknown Source)
at javax.security.auth.login.LoginContext$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
at javax.security.auth.login.LoginContext.login(Unknown Source)
at test.HelloWorld.login(HelloWorld.java:167)
at test.HelloWorld.doGet(HelloWorld.java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
11:05:25,750 ERROR [STDERR] javax.security.auth.login.LoginException: Missing users.properties file.
11:05:25,750 ERROR [STDERR] at org.jboss.security.auth.spi.UsersRolesLoginModule.login(UsersRolesLoginModule.java:148)
11:05:25,751 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:05:25,751 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
11:05:25,751 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
11:05:25,751 ERROR [STDERR] at java.lang.reflect.Method.invoke(Unknown Source)
11:05:25,751 ERROR [STDERR] at javax.security.auth.login.LoginContext.invoke(Unknown Source)
11:05:25,751 ERROR [STDERR] at javax.security.auth.login.LoginContext.access$000(Unknown Source)
11:05:25,751 ERROR [STDERR] at javax.security.auth.login.LoginContext$4.run(Unknown Source)
11:05:25,751 ERROR [STDERR] at java.security.AccessController.doPrivileged(Native Method)
11:05:25,751 ERROR [STDERR] at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
11:05:25,751 ERROR [STDERR] at javax.security.auth.login.LoginContext.login(Unknown Source)
11:05:25,751 ERROR [STDERR] at test.HelloWorld.login(HelloWorld.java:167)
11:05:25,751 ERROR [STDERR] at test.HelloWorld.doGet(HelloWorld.java:66)
11:05:25,751 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
11:05:25,751 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
11:05:25,751 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
11:05:25,752 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
11:05:25,752 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
11:05:25,753 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
11:05:25,753 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
11:05:25,753 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
11:05:25,753 ERROR [STDERR] at java.lang.Thread.run(Unknown Source)