我玩Wildfly-9.0.1.Final
和JAAS
,但我並沒有這麼多的樂趣..我實現我的自定義登錄模塊:Wildfly和JAAS登錄模塊
public class MongoLoginModule implements LoginModule {
@Inject
protected MongoDB mongoDb;
protected Subject subject;
protected Principal identity;
protected boolean loginOk;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
private Logger log = LoggerFactory.getLogger(MongoLoginModule.class);
public boolean abort() throws LoginException {
log.info("abort!");
subject = null;
return true;
}
public boolean commit() throws LoginException {
// TODO Auto-generated method stub
log.info("commit!");
if(loginOk) {
UserGroup userGroup = new UserGroup("Roles");
userGroup.addMember(new RolePrincipal("userA"));
subject.getPrincipals().add(userGroup);
subject.getPublicCredentials().add(userGroup);
return true;
}
return false;
}
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
log.info("Initializing MongoLoginModule.");
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
}
public boolean login() throws LoginException {
log.info("login requested.");
NameCallback nameCallback = new NameCallback("username:");
PasswordCallback passwordCallback = new PasswordCallback("password:", false);
try {
callbackHandler.handle(new Callback[]{nameCallback, passwordCallback});
String username = nameCallback.getName();
String password = new String(passwordCallback.getPassword());
log.info("check credentials for: "+username);
if(username.equals("jim") && password.equals("jim")) {
loginOk = true;
identity = new UserPrincipal(username);
subject.getPrincipals().add(identity);
subject.getPublicCredentials().add(identity);
return true;
}
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedCallbackException e) {
e.printStackTrace();
}
return false;
}
public boolean logout() throws LoginException {
if(subject != null && identity != null) {
subject.getPrincipals().remove(identity);
return true;
}
return false;
}
public Document getUserByName(String userName) {
FindIterable<Document> results = mongoDb.getCollection().find(new Document("username", userName));
return results.iterator().next();
}
public void getRoles() {
// FindIterable<Document> results = mongoDb.getCollection().find(new Document("username", userName));
// results.iterator().next().get
}
它並不完美,但它足夠多的現在。這個純粹的JAAS登錄模塊是我的Wildfly中的一個模塊。我這樣配置安全域:
<security-domain name="MongoLoginRealm" cache-type="default">
<authentication>
<login-module code="it.bytebear.jaas.mongo.module.MongoLoginModule" flag="required" module="login.mongodb">
<module-option name="mongodb.uri" value="mongodb://localhost:21017/test?collection"/>
</login-module>
</authentication>
</security-domain>
我實現了一些REST風格的web服務來做一些測試。我只是張貼了相關代碼:
...
@POST
@Path("/login")
@PermitAll
@Consumes(MediaType.APPLICATION_JSON)
// @Consumes("application/x-authc-username-password+json")
public Response login(User userCredentials) {
log.info("logging in.");
try {
MongoModuleCallbackHandler handler = new MongoModuleCallbackHandler();
handler.setUsername(userCredentials.getUserName());
handler.setPassword(userCredentials.getPassword().toCharArray());
LoginContext loginContext = new LoginContext("MongoLoginRealm", handler);
loginContext.login();
Subject subject = loginContext.getSubject();
List<String> roles = new ArrayList<String>();
for (Principal p : subject.getPrincipals()) {
roles.add(p.getName());
}
userCredentials.setRoles((String[]) roles.toArray());
return Response.ok().entity(userCredentials)
.type(MediaType.APPLICATION_JSON_TYPE).build();
} catch (Exception e) {
log.error("login fails.", e);
return Response.status(Status.FORBIDDEN).entity("Not logged")
.type(MediaType.APPLICATION_JSON_TYPE).build();
}
}
...
在web.xml
auth-method
是BASIC
和realm-name
爲MongoLoginRealm
,在jboss-web.xml
和實例LoginContext
時使用的相同。當我調用login
方法,我得到這個異常:
22:39:49,421 ERROR [it.bytebear.web.mongo.UserServices] (default task-1) login fails.: javax.security.auth.login.LoginException: impossibile trovare la classe Login
Module: it.bytebear.jaas.mongo.module.MongoLoginModule from [Module "deployment.MongoWebTest.war:main" from Service Module Loader]
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:822)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:695)
at javax.security.auth.login.LoginContext.login(LoginContext.java:594)
at it.bytebear.web.mongo.UserServices.login(UserServices.java:66)
是從未執行過我的登錄模塊。我錯過了什麼?
更新: 將登錄模塊.jar移動到它工作的Web應用程序中。也許我的Wild is有一些問題。這裏是我的模塊結構:
%wildfly_home%/modules/system/layers/base/login/mongodb/main/module.xml
%wildfly_home%/modules/system/layers/base/login/mongodb/main/mongo-java-driver-3.0.3.jar
%wildfly_home%/modules/system/layers/base/login/mongodb/main/MongoLoginModule.jar
,這是module.xml
:
<module xmlns="urn:jboss:module:1.1" name="login.mongodb">
<resources>
<resource-root path="MongoLoginModule.jar"/>
<resource-root path="mongo-java-driver-3.0.3.jar"/>
</resources>
<dependencies>
<module name="org.apache.log4j"/>
<module name="javax.api"/>
<module name="org.slf4j"/>
</dependencies>
</module>
我必須弄清楚爲什麼登錄模塊不可達的Wildfly模塊。
您是如何打包並安裝包含您的自定義LoginModule的服務器模塊(「login.mongodb」)的?您可以嘗試在第一步避免使用服務器模塊並將自定義登錄模塊包含在您的應用程序WAR中(在此情況下,將standalone.xml中的模塊屬性從安全域配置中移除)。 – kwart
我在閱讀你的評論之前做了你建議的測試。我將登錄模塊jar包含在Web應用程序中,並從standalone.xml登錄模塊節點中刪除了模塊屬性。它的工作原理,現在我必須弄清楚爲什麼登錄模塊無法作爲Wildfly模塊訪問。我更新了我的問題。 – Francesco