2014-07-23 1 views
1

mongoDB 컬렉션에있는 사용자를 인증하기 위해 사용자 정의 LoginModule을 만들었습니다. 제 경우에는 한 페이지 당 하나의 역할이 필요합니다 ... JSF와 JAAS 인증을 이미 사용했지만이 경우 예상대로 작동하지 않습니다 ... 항상 403 오류 (금지됨)를 반환합니다. URL의 매핑은 분명히 OK입니다.Java/WildFly/MongoDB/JAAS - 인증은 항상 403을 반환합니다. - Forbidden

  • 응용 프로그램 < -root
    • 페이지
      • 내 보호 페이지 (페이지 당 하나 개의 역할)
    • login.html
    • login_error : 내 페이지 계층 구조의

      .html

    • index.html을

내 구성을 따르

의 jboss-web.xml을

<jboss-web> 
    <security-domain>nfceSecurityDomain</security-domain> 
    <disable-audit>true</disable-audit> 
</jboss-web> 

web.xml을

<session-config> 
    <session-timeout>30</session-timeout> 
</session-config> 

<login-config> 
    <auth-method>FORM</auth-method> 
    <form-login-config> 
      <form-login-page>/app/login.html</form-login-page> 
      <form-error-page>/app/login_error.html</form-error-page> 
    </form-login-config> 
</login-config> 

<security-role> 
    <role-name>VISUALIZAR_NOTAS</role-name> 
</security-role> 
<security-role> 
    <role-name>GESTAO_CERTIFICADO</role-name> 
</security-role> 
<security-role> 
    <role-name>GESTAO_EMPRESA</role-name> 
</security-role> 
<security-role> 
    <role-name>DOWNLOAD_XML</role-name> 
</security-role> 
<security-role> 
    <role-name>INUTILIZACAO</role-name> 
</security-role> 

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>index</web-resource-name> 
     <url-pattern>/app/index.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
      <role-name>VISUALIZAR_NOTAS</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>orderList</web-resource-name> 
     <url-pattern>/app/pages/orderlist.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>VISUALIZAR_NOTAS</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>certificateConfigurations</web-resource-name> 
     <url-pattern>/app/pages/certifiedlist.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>GESTAO_CERTIFICADO</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>enterpriseConfigurations</web-resource-name> 
     <url-pattern>/app/pages/enterpriselist.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>GESTAO_EMPRESA</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>xmlDownload</web-resource-name> 
     <url-pattern>/app/pages/orderdownload.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>DOWNLOAD_XML</role-name> 
    </auth-constraint> 
</security-constraint> 
<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>invalidate</web-resource-name> 
     <url-pattern>/app/pages/orderInvalidate.html</url-pattern> 
     <http-method>POST</http-method> 
     <http-method>GET</http-method> 
     <http-method>PUT</http-method> 
     <http-method>DELETE</http-method> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>INUTILIZACAO</role-name> 
    </auth-constraint> 
</security-constraint> 

standalone.xml

나는 standalone.xml에 다음과 같은 속성을 추가 한

public class JAASLoginModule implements LoginModule { 

    private static final Logger LOG = Logger.getLogger(JAASLoginModule.class); 

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

    private boolean succeeded = false; 
    private boolean commitSucceeded = false; 

    private String username = null; 
    private String _idUser = ""; 
    private char[] password = null; 

    private Principal userPrincipal = null; 
    private Principal passwordPrincipal = null; 

    private ConnectionMongoUtil connectionMongoUtil; 

    public JAASLoginModule() { 
     super(); 
    } 

    @Override 
    public void initialize(Subject subject, CallbackHandler callbackHandler, 
      Map<String, ?> sharedState, Map<String, ?> options) { 
     this.subject = subject; 
     this.callbackHandler = callbackHandler; 
     this.sharedState = sharedState; 
     this.options = options; 
    } 

    @Override 
    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("username"); 
     callbacks[1] = new PasswordCallback("password: ", false); 

     try { 
      callbackHandler.handle(callbacks); 
      username = ((NameCallback) callbacks[0]).getName(); 
      password = ((PasswordCallback) callbacks[1]).getPassword(); 

      if (username == null || password == null) { 
       LOG.error("Callback handler does not return login data properly"); 
       throw new LoginException(
         "Callback handler does not return login data properly"); 
      } 

      if (isValidUser()) { // validate user. 
       succeeded = true; 
       return true; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedCallbackException e) { 
      e.printStackTrace(); 
     } 

     return false; 
    } 

    @Override 
    public boolean commit() throws LoginException { 
     if (succeeded == false) { 
      return false; 
     } else { 
      userPrincipal = new JAASUserPrincipal(username); 
      if (!subject.getPrincipals().contains(userPrincipal)) { 
       subject.getPrincipals().add(userPrincipal); 
       LOG.debug("User principal added:" + userPrincipal); 
      } 
      passwordPrincipal = new JAASPasswordPrincipal(new String(password)); 
      if (!subject.getPrincipals().contains(passwordPrincipal)) { 
       subject.getPrincipals().add(passwordPrincipal); 
       LOG.debug("Password principal added: " + passwordPrincipal); 
      } 

      List<String> roles = getRoles(); 
      for (String role : roles) { 
       Principal rolePrincipal = new JAASRolePrincipal(role); 
       if (!subject.getPrincipals().contains(rolePrincipal)) { 
        subject.getPrincipals().add(rolePrincipal); 
        LOG.debug("Role principal added: " + rolePrincipal); 
       } 
      } 

      commitSucceeded = true; 
      LOG.info("Login subject were successfully populated with principals and roles"); 
      return true; 
     } 
    } 

    @Override 
    public boolean abort() throws LoginException { 
     if (succeeded == false) { 
      return false; 
     } else if (succeeded == true && commitSucceeded == false) { 
      succeeded = false; 
      username = null; 
      if (password != null) { 
       password = null; 
      } 
      userPrincipal = null; 
     } else { 
      logout(); 
     } 
     return true; 
    } 

    @Override 
    public boolean logout() throws LoginException { 
     subject.getPrincipals().remove(userPrincipal); 
     succeeded = false; 
     succeeded = commitSucceeded; 
     username = null; 
     if (password != null) { 
      for (int i = 0; i < password.length; i++) { 
       password[i] = ' '; 
       password = null; 
      } 
     } 
     userPrincipal = null; 
     return true; 
    } 

    private boolean isValidUser() throws LoginException { 

     try { 
      BasicDBObject search = new BasicDBObject(); 
      search.put("email", username); 
      connectionMongoUtil = new ConnectionMongoUtil(); 
      DBObject user = connectionMongoUtil.getCollection("User").findOne(search); 

      if (user == null){ 
       LOG.debug("USUÁRIO NÃO LOCALIZADO!"); 
       return false; 
      }else{ 
       if (new String(password).equals(user.get("password"))){ 
        _idUser = user.get("_id").toString(); 
        return true; 
       }else{ 
        LOG.debug("SENHA INVÁLIDA PARA O USUÁRIO " + username); 
       } 
      } 

      return false; 
     } catch (Exception e) { 
      LOG.error("Error when loading user " + username + " from the database \n", e); 
     } 

     return false; 
    } 

    /** 
    * Returns list of roles assigned to authenticated user. 
    * 
    * @return 
    */ 
    private List<String> getRoles() { 
     BasicDBObject search = new BasicDBObject(); 
     search.put("_idUser", _idUser); 
     DBObject userModules = connectionMongoUtil.getCollection("UserModules").findOne(search); 
     String jsonArrayModules = userModules.get("_idModules").toString(); 

     String[] modules = null; 
     try { 
      modules = new ObjectMapper().readValue(jsonArrayModules, String[].class); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     List<String> modulesList = new ArrayList<String>(); 
     for (String _idModule : modules) { 
      DBObject module = connectionMongoUtil.getCollection("Module").findOne(new BasicDBObject("_id", new ObjectId(_idModule))); 
      if (module != null){ 
       modulesList.add(module.get("name").toString()); 
      } 
     } 

     return modulesList; 
    } 
} 

JAAS에 의해 생성 된 로그를 참조하고, 돈 :

<subsystem xmlns="urn:jboss:domain:security:1.2"> 
      <security-domains> 
       <security-domain name="nfceSecurityDomain" cache-type="default"> 
        <authentication> 
         <login-module code="br.com.ciss.nfce.security.JAASLoginModule" flag="required"/> 
        </authentication> 
       </security-domain> 
      </security-domains> 
     </subsystem> 

그리고 여기이 로그인 모듈의 내 구현하여 MongoDB에서 사용자와 역할을 얻는 것입니다 't는 내 사용자에게 모든 역할을 추가 한, 내 MongoDB의 컬렉션에서

<logger category="org.jboss.security"> 
    <level name="ALL"/> 
</logger> 

... 오류 로그를 가지고 있고, 내가 로그인 할 때, 나는 로그인 할 수 있지만, 모든 페이지가 고정되어 403 오류를 반환합니다.

아무도 도와 줄 수 있습니까? 아마 403 오류가 발생하는 작은 세부 사항입니다 ...

감사합니다.

+0

사용중인 실제 MongoDB 쿼리와 반환 값을 로깅 해 보셨습니까? JAAS에서 디버그 정보를 추가 할 위치가 확실하지 않다면 MongoDB [database profiler] (http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/)를 사용해보십시오. 레벨 2 (느린 쿼리가 아닌 모든 쿼리). – Stennie

+0

안녕하세요, 귀하의 답변 주셔서 감사합니다 ... 나는 사용자와 역할을 JAASLoginModule에서 수정했기 때문에 문제가 mongoDB 쿼리가 아니라고 생각합니다. 동일한 오류가 발생합니다. 오류가 JBoss 구성에 있다고 생각합니다. – siega

+0

몇 가지 테스트를하기 위해이 프로젝트를 변경했으며 내 Google 드라이브에서 공유했습니다 ... Google 드라이브에서 프로젝트 (일식), 독립 실행 형 .xml 파일 및 페이지에 액세스하려고 할 때 생성되는 로그 ... 프로젝트에는 LoginModule의 두 가지 구현이 있지만 JAASLoginModule 만 사용합니다. 누군가가 나를 도울 수 있다면, 나는 매우 감사하게 될 것입니다 ... https://drive.google.com/folderview?id=0B_GgtF8zczPWbnV2cmVxZDlvQ3c&usp=sharing – siega

답변

0

이 문제를 해결하는 유일한 방법은 여전히 ​​좋은없이, 스프링 시큐리티에 의해 JAAS를 변경 :

0

에 모듈을 배포 봤어이다 해결책. 내가 바로 그 같은 문제가 없었다

...

어떤 상황 : 나는 원활하게 실행 JAAS를 (직접 javax.security.auth.spi.LoginModule을 구현)를 사용하여 "건강한"자바 웹 응용 프로그램을 가지고 Tomcat7. 고객 요구 사항이 장면에 나타났습니다. "JBoss 7.1.1에서 실행해야합니다" WTF? 부 버전 및 패치조차!?!에

손 : 그래서 나는 모든 구성을 한 자바 (8) 코드와 JAX-RS와 몇 가지 단점을 가지고 있지만, 내 응용 프로그램은 J 보스 7.1.1에 성공적으로 배포 된 결국, 또 다른 이야기이다.

문제 : I 로그인 콘솔에서 볼 수는 성공적인했지만, 모든 주체 (CallerPrincipal 및 UserRoles)이 확인되었다 디버깅하는 동안 모든 요청은 HTTP 403

을 반환했다.

솔루션는 ... 또한

, 나는 모든 요청이 통과해야 할 하나의 추상적 인 오케스트레이션에 대한 BaseServlet 어느을 가지고 있지만 HTTP 403은 도달하기 전에 발생했습니다 : 그래서 내가 발견 한 모든 JBoss의 문서 JAAS에 관해서는, 개발자가 커스터마이즈 된 LoginModule를 확장하도록 (듯이) 조언하고 있으므로, 파기에 착수했습니다.

org.jboss.security.auth.spi.AbstractServerLoginModule은 "JBossSX 표준 ID 및 역할 저장의 Subject 사용 패턴"을 사용합니다.

패턴을 설명하는 데 그리 심혈을 기울이지는 않았지만 컨테이너 측의 인증 프로세스를 래핑하는 'JBossWebRealm'을 이름이 "Roles"인 java.security.acl.Group 구현을 기대하고 있습니다. 모든 Principal (CallerPrincipal 및 UserRoles)을 멤버로 사용합니다 (Membership Of The JAASRealm).

이 개체는 보안 검사에 사용됩니다.

public boolean commit() throws LoginException { 

    // some validation code here 

    Set<Principal> principals = subject.getPrincipals(); 

    // ensure principals contains (CallerPrincipal and UserRoles) 

    createRolesGroup(principals); 

    return true; 
} 

private void createRolesGroup(Set<Principal> principals) { 

    // Thee java.security.acl.Group implementation 
    SecurityGroup rolesGroup = new SecurityGroup("Roles"); 

    Iterator<Principal> iter = principals.iterator(); 

    while(iter.hasNext()) { 
     Object principal = iter.next(); 
     if(!(principal instanceof Group)){ 
     rolesGroup.addMember((Principal)principal); 
    } 

    principals.add(rolesGroup); 
} 

을 그리고 매력처럼 작동 : 이야기의

종료, 내 로그인 모듈 구현에이 방법을 추가했습니다.

희망이 있습니다.

관련 문제