2015-10-18 5 views
1

Я играю с 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> 

Я внедрил некоторые веб-службы RESTful, чтобы сделать некоторые тесты. Я только размещение соответствующий код:

... 

@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) 

Мой модуль Войти никогда не была выполнена. Что мне не хватает?

UPDATE: Перемещение модуля входа в систему .jar в веб-приложение работает. Возможно, в моей Wildfly есть что-то не так. Вот мой модуль структуры:

%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.

+1

Как вы упаковали и установили серверный модуль («login.mongodb»), который содержит ваш пользовательский LoginModule? Вы можете попробовать на первом шаге, чтобы избежать использования серверных модулей и включить пользовательский модуль входа в приложение WAR (в таком случае удалите атрибут модуля из конфигурации домена безопасности в файле standalone.xml). – kwart

+0

Я сделал тест, который вы предлагаете, прежде чем читать свой комментарий. Я включаю банку модуля входа в веб-приложение и удаляю атрибут модуля из моего узла login-модуля standalone.xml. Он работает, теперь мне нужно выяснить, почему модуль входа не доступен, как модуль Wildfly. Я обновил свой вопрос. – Francesco

ответ

1

Мое приложение не может найти модуль, потому что я забыл добавить Dependency на это MANIFEST или объявить login.mongodb глобальным модулем в Wildfly. Спасибо @kwart за ваше предложение и ваш ответ, вы указываете мне в правильном направлении.

1

Это, вероятно, проблема (или особенность) WildFly. Я сообщил об этом как WildFly JIRA WFLY-5569.

Вы все равно можете использовать стандартную сервлет аутентификацию, которая работает правильно.

Добавить WEB-INF/jboss-web.xml файл развертывания:

<jboss-web> 
    <security-domain>MongoLoginRealm</security-domain> 
</jboss-web> 

Настройте свой код, чтобы использовать HttpServletRequest.login(String, String) методу

@Context 
private HttpServletRequest req; 

@POST 
@Path("/login") 
@PermitAll 
@Consumes(MediaType.APPLICATION_JSON) 
public Response login(User userCredentials) { 
    try { 
     req.login(userCredentials.getUserName(), 
      userCredentials.getPassword()); 
     Subject subject = org.jboss.security.SecurityContextAssociation.getSubject(); 
     Optional<Group> rolesGroup = subject.getPrincipals(Group.class).stream().filter(p -> "Roles".equals(p.getName())) 
       .findFirst(); 
     if (rolesGroup.isPresent()) { 
      List<String> roleNames = Collections.list(rolesGroup.get().members()).stream().map(p -> p.getName()) 
        .collect(Collectors.toList()); 
      // ... 
     } else { 
      // ... 
     } 
    } catch (ServletException e) { 
     log.error("login fails.", e); 
     return Response.status(Status.FORBIDDEN).entity("Not logged") 
      .type(MediaType.APPLICATION_JSON_TYPE).build(); 
    } 
} 
Смежные вопросы