2014-05-23 6 views
6

웹 서비스를 통해 액세스하고 JPA 액세스 DB의 사용자 이름과 암호를 확인하는 사용자 정의 loginModule을 구현했습니다. jboss 7.1에서 실행하고 괜찮 았지만 Wildfly로 옮긴 후 (올바른 구성이라고 생각하는 부분을 추가하면) wildfly 클래스 내부에서 형태소 분석을하는 NullPointerException이 발생합니다. 어떤 아이디어?Wildfly 사용자 정의 로그인 모듈 오류

public class JPALoginModule implements LoginModule { 

    CallbackHandler callbackHandler; 
    Subject subject; 
    Map sharedState; 
    Map options; 

    boolean success; 

    LoginVerifier loginVerifier; 

    @Override 
    public void initialize(Subject subject, CallbackHandler callbackHandler, 
     Map<String, ?> sharedState, Map<String, ?> options) { 
     System.out.println("JPALoginModule.initialize()"); 
     this.callbackHandler = callbackHandler; 
     this.subject = subject; 
     this.sharedState = sharedState; 
     this.options = options; 
     InitialContext context = null; 
     try { 
      context = new InitialContext(); 
     } catch (NamingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      this.loginVerifier = (LoginVerifier) context.lookup("java:global/jaas.ear/jaas.ejb/LoginVerifierBean!beans.LoginVerifier"); 
     } catch (NamingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public boolean login() throws LoginException { 
     System.out.println("JPALoginModule.login()"); 
     try { 
      // Setup default callback handlers. 
      Callback[] callbacks = new Callback[] { 
       new NameCallback("Username: "), 
       new PasswordCallback("Password: ", false) }; 

      callbackHandler.handle(callbacks); 

      String username = ((NameCallback) callbacks[0]).getName(); 
      String password = new String(
       ((PasswordCallback) callbacks[1]).getPassword()); 

      success = loginVerifier.verify(username, password); 

      if (!success) { 
       throw new LoginException(
        "Authentication Failed: Wrong Password"); 
      } else if (success) { 
       return true; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedCallbackException e) { 
      e.printStackTrace(); 
     } 
     catch (NullPointerException e) { 
      System.out.println(e.getMessage()+" "+e.getLocalizedMessage()); 
     } 
     return false; 
    } 

    @Override 
    public boolean commit() throws LoginException { 
     if (success) { 
      if (subject.isReadOnly()) { 
       throw new LoginException("subject is read only"); 
      } 
      if (callbackHandler instanceof PassiveCallBackHandler) { 
       ((PassiveCallBackHandler) callbackHandler).clearPassword(); 
      } 
      return true; 
     } 
     else { 
      return true; 
     } 
    } 

    @Override 
    public boolean abort() throws LoginException { 
     logout(); 
     return true; 
    } 

    @Override 
    public boolean logout() throws LoginException { 
     if (callbackHandler instanceof PassiveCallBackHandler) { 
      ((PassiveCallBackHandler) callbackHandler).clearPassword(); 
     } 
     return true; 
    } 

내 제이 보스 - web.xml의 :

<?xml version="1.0" encoding="UTF-8"?> 
<jboss-web> 
    <security-domain>java:/jaas/jpa-login-module</security-domain> 
</jboss-web> 

내 web.xml의 :

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
version="3.0"> 
<display-name>jass.ws</display-name> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name></web-resource-name> 
     <url-pattern>/*</url-pattern> 
     <http-method>GET</http-method> 
     <http-method>POST</http-method> 
    </web-resource-collection> 
</security-constraint> 
<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>jpa-login-module</realm-name> 
</login-config> 

18:48:21,417 ERROR [io.undertow.request] (default task-3) UT005023: Exception handling request to /jass.ws/jaas/verifier/authenticateWithBasicUsernamePasswordAuth: java.lang.RuntimeException: java.lang.NullPointerException 
    at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:126) 
    at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verify(JAASIdentityManagerImpl.java:82) 
    at io.undertow.security.impl.BasicAuthenticationMechanism.authenticate(BasicAuthenticationMechanism.java:110) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:281) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:298) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:268) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:131) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:106) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:99) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:50) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687) [undertow-core-1.0.0.Final.jar:1.0.0.Final] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51] 
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51] 
Caused by: java.lang.NullPointerException 
    at org.wildfly.extension.undertow.security.AccountImpl.<init>(AccountImpl.java:61) 
    at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:123) 
... 29 more 

내 사용자 정의 로그인 모듈입니다 691,363,210

내 standalone.xml 관련 구성 :

<security-domains> 
    <security-domain name="jpa-login-module" cache-type="default"> 
     <authentication> 
      <login-module code="com.jaas.JPALoginModule" flag="required"/> 
     </authentication> 
    </security-domain> 
    <security-domain name="jpa-password-username" cache-type="default"> 
     <authentication> 
      <login-module code="com.jaas.JPAUsernamePasswordLoginModule" flag="required"/> 
     </authentication> 
    </security-domain> 
    <security-domain name="other" cache-type="default"> 
     <authentication> 
      <login-module code="Remoting" flag="optional"> 
       <module-option name="password-stacking" value="useFirstPass"/> 
      </login-module> 
      <login-module code="RealmDirect" flag="required"> 
       <module-option name="password-stacking" value="useFirstPass"/> 
      </login-module> 
     </authentication> 
    </security-domain> 
    <security-domain name="jboss-web-policy" cache-type="default"> 
     <authorization> 
      <policy-module code="Delegating" flag="required"/> 
     </authorization> 
    </security-domain> 
    <security-domain name="jboss-ejb-policy" cache-type="default"> 
     <authorization> 
      <policy-module code="Delegating" flag="required"/> 
     </authorization> 
    </security-domain> 
</security-domains> 
+0

버전은 무엇을 작동? 8.1.0.CR2를 사용해 본 사람이라면 아마 버그처럼 보일 수도 있습니다. –

답변

2

NPE는 확실히 제이보스의 물러 확장의 버그입니다. 새로운 JIRA - WFLY-3416을 만들었습니다.

그럼에도 불구하고 JBoss AS 및 Wildfly에 대한 사용자 정의 로그인 모듈을 작성하는 안전한 방법은 org.jboss.security.auth.spi.AbstractServerLoginModule입니다. 교장 인스턴스 (identity 멤버 변수에서) 생성되기 때문에 사용자가 성공적으로 인증되면, NullPointerException가 방지 할 수

import java.security.Principal; 
import java.security.acl.Group; 
import java.util.Map; 

import javax.naming.InitialContext; 
import javax.naming.NamingException; 
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.login.LoginException; 

import org.jboss.security.auth.spi.AbstractServerLoginModule; 

public class JPALoginModule extends AbstractServerLoginModule { 

    LoginVerifier loginVerifier; 
    java.security.Principal identity; 

    @Override 
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { 
     System.out.println("JPALoginModule.initialize()"); 
     super.initialize(subject, callbackHandler, sharedState, options); 
     InitialContext context = null; 
     try { 
      context = new InitialContext(); 
     } catch (NamingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      this.loginVerifier = (LoginVerifier) context 
        .lookup("java:global/jaas.ear/jaas.ejb/LoginVerifierBean!beans.LoginVerifier"); 
     } catch (NamingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public boolean login() throws LoginException { 
     System.out.println("JPALoginModule.login()"); 
     try { 
      // Setup default callback handlers. 
      Callback[] callbacks = new Callback[] { new NameCallback("Username: "), new PasswordCallback("Password: ", false) }; 

      callbackHandler.handle(callbacks); 

      String username = ((NameCallback) callbacks[0]).getName(); 
      String password = new String(((PasswordCallback) callbacks[1]).getPassword()); 

      if (!loginVerifier.verify(username, password)) { 
       throw new LoginException("Authentication Failed: Wrong Password"); 
      } 
      try { 
       identity = createIdentity(username); 
      } catch (Exception e) { 
       throw new LoginException("Unable to Create Identity"); 
      } 
      return true; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedCallbackException e) { 
      e.printStackTrace(); 
     } catch (NullPointerException e) { 
      System.out.println(e.getMessage()+" "+e.getLocalizedMessage()); 
     } 
     return false; 
    } 

    @Override 
    public boolean commit() throws LoginException { 
     if (identity != null) { 
      if (subject.isReadOnly()) { 
       throw new LoginException("subject is read only"); 
      } 
      if (callbackHandler instanceof PassiveCallBackHandler) { 
       ((PassiveCallBackHandler) callbackHandler).clearPassword(); 
      } 
     } 
     return super.commit(); 
    } 

    @Override 
    public boolean abort() throws LoginException { 
     logout(); 
     return true; 
    } 

    @Override 
    public boolean logout() throws LoginException { 
     if (callbackHandler instanceof PassiveCallBackHandler) { 
      ((PassiveCallBackHandler) callbackHandler).clearPassword(); 
     } 
     return super.logout(); 
    } 

    @Override 
    protected Principal getIdentity() { 
     return identity; 
    } 

    @Override 
    protected Group[] getRoleSets() throws LoginException { 
     return new Group[0]; 
    } 
} 

이 :

같은 것을보십시오.

4

나는 그 이유를 알아 냈다. 왜냐하면 인증 후에 프린시 펄을 추가하지 않았기 때문이다.

그래서 나는이 추가 :

if (!success) { 
    throw new LoginException(
     "Authentication Failed: Wrong Password"); 
} else if (success) { 
    Principal passPrincipal = new UsernamePrincpal(username); 
    subject.getPrincipals().add(passPrincipal); 
    subject.getPrivateCredentials().add(password); 
    return true; 
} 

을 그리고 제이보스의