Ahoj, vsichni,

na j2ee projektu se snazim zavest authentication + authorization/role
management, kde uzivatele a role jsou definovani v LDAPu. Protoze jde o
ciste enterprise projekt deployovany na JBoss AS, rozhodl jsem pouzit JAAS s
implementaci nabizenou JBoss serverem. Mym cilem je overeni uzivatele proti
LDAPu a nasledne pouzivani autorizacnich anotaci na EJB (@RollesAllowed()) a
webove vrstve (request.isUserInRole()).

Samotny login proti LDAPu s pomoci
org.jboss.security.auth.spi.LdapExtLoginModule se mi podaril celkem snadno.
Spravne se overi heslo a k uzivateli se dotahnou jeho role.

Co se mi ale ani za nic nedari, je Subject resp. Principal ziskany pri
loginu pouzit pri volani EJB metod a pristupu na webove stranky. Mam pocit,
ze misto toho, aby se mi Subject zpropagoval do EJBContext a ServletContext,
po loginu se proste zahodi.

Hledani na Googlu a v odpovidajici literature mi rika jen, ze by vsechno
melo fungovat spravne. Jenze nefunguje.
Dokazete mi, prosim, nekdo poradit, co delam spatne?

Diky,

C.

---------------------------------------------------------------------
Nastaveni login-config.xml:

<policy>
   <application-policy name="localLdapPolicy">
    <authentication>
       <login-module code="org.jboss.security.auth.spi.LdapExtLoginModule"
flag="required" >
       <module-option
name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
       <module-option
name="java.naming.provider.url">ldap://localhost:10389</module-option>
       <module-option
name="java.naming.security.authentication">simple</module-option>
       <module-option name="bindDN">uid=admin,ou=system</module-option>
       <module-option name="bindCredential">secret</module-option>
       <module-option
name="baseCtxDN">ou=People,dc=example,dc=com</module-option>
       <module-option name="baseFilter">(uid={0})</module-option>
       <module-option
name="rolesCtxDN">ou=Roles,dc=example,dc=com</module-option>
       <module-option name="roleFilter">(member={1})</module-option>
       <module-option name="roleAttributeID">cn</module-option>
       <module-option name="searchScope">ONELEVEL_SCOPE</module-option>
       <module-option name="allowEmptyPasswords">false</module-option>
    </login-module>
   </authentication>
  </application-policy>
</policy>

---------------------------------------------------------------------
descriptor xxx-ejb.jar/META-INF/jboss.xml :

<jboss>
       <security-domain>localLdapPolicy</security-domain>
</jboss>

--------------------------------------------------------------------
descriptor xxx.war/WEB-INF/jboss-web.xml

<jboss-web>
  <context-root>/LDAPLoginTestFacade</context-root>
  <security-domain>java:/jaas/localLdapPolicy</security-domain>
</jboss-web>

---------------------------------------------------------------------
Servlet, ktery prijme jmeno/heslo zadane uzivatelem a pokusi se o login:

public class LoginServlet extends HttpServlet {

    static final Logger logger =
Logger.getLogger(LoginServlet.class.getName());

    @EJB(beanName = "LoginFacade")
    LoginFacadeLocal loginFacade;

    @EJB(beanName = "TestService")
    TestServiceLocal testService;

    protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
    throws ServletException, IOException {

        try {
            String user = request.getParameter("j_username");
            String password = request.getParameter("j_password");

            logger.info("logging user="+user+",pass="+password);

            testEJBmethods(); // podle ocekavani vyhodi chybu (uzivatel neni
prihlasen)

            loginFacade.login(user, password); // prihlaseni uspesne
probehne

            testEJBmethods(); // podle ocekavani by melo projit, ale pada,
protoze Principal se neni asociovany s kontextem aplikace (viz. log)

            logger.info("Session id="+request.getSession().getId());

            if (request.isUserInRole("Admins")){
                logger.info("User has Admins role");
            }

            if (request.getUserPrincipal() != null) {
                logger.info("User logged in : "+
request.getUserPrincipal().getName());
            }

            response.sendRedirect(this.getServletContext().getContextPath()
+ "/index.jsp");

        } catch (LoginException ex) {
            logger.fatal("JAAS Login Failed: " + ex);
            response.sendRedirect(this.getServletContext().getContextPath()
+ "/login.jsp");
        }
    }

    private void testEJBmethods() {

        try {
            // bean method with @AllowedRoles("Operators")
            testService.testOperators();
        } catch (EJBAccessException ex) {
            logger.error("testOperators access failed " + ex);
        }

        try {
            // bean method with @AllowedRoles("Admins")
            testService.testAdmins();
        } catch (EJBAccessException ex) {
            logger.error("testAdmin access failed " + ex);
        }
    }
}

---------------------------------------------------------------------
Beana provadejici autentizaci oproti LDAPu (ta probehne uspesne)


@Stateless
public class LoginFacade implements LoginFacadeLocal{
     static Logger logger = Logger.getLogger(LoginFacade.class.getName());

    @PermitAll
    public void login(String user, String password) throws LoginException {

            CallbackHandler handler = new UserPassHandler(user, password);

            LoginContext lc = new LoginContext("localLdapPolicy", handler);
            lc.login();


            Subject subject = lc.getSubject();
            if (subject != null) {
                logger.info("Subject retrieved: " + subject);
            }
    }
}
---------------------------------------------------------------------
server.log:

2010-12-07 15:12:31,406 TRACE
[org.jboss.security.auth.login.XMLLoginConfigImpl] (http-0.0.0.0-8080-1)
Begin getAppConfigurationEntry(localLdapPolicy), size=11
2010-12-07 15:12:31,406 TRACE
[org.jboss.security.auth.login.XMLLoginConfigImpl] (http-0.0.0.0-8080-1) End
getAppConfigurationEntry(localLdapPolicy), authInfo=AppConfigurationEntry[]:
[0]
LoginModule Class: org.jboss.security.auth.spi.LdapExtLoginModule
ControlFlag: LoginModuleControlFlag: required
Options:
name=baseFilter, value=(uid={0})
name=java.naming.security.authentication, value=simple
name=java.naming.factory.initial, value=com.sun.jndi.ldap.LdapCtxFactory
name=allowEmptyPasswords, value=false
name=roleFilter, value=(member={1})
name=bindCredential, value=****
name=bindDN, value=uid=admin,ou=system
name=java.naming.provider.url, value=ldap://localhost:10389
name=rolesCtxDN, value=ou=Roles,dc=example,dc=com
name=baseCtxDN, value=ou=People,dc=example,dc=com
name=searchScope, value=ONELEVEL_SCOPE
name=roleAttributeID, value=cn

2010-12-07 15:12:31,422 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1)
initialize
2010-12-07 15:12:31,422 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1)
Security domain: localLdapPolicy
2010-12-07 15:12:31,422 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1) login
2010-12-07 15:12:31,453 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1)
Assign user to role Admins
2010-12-07 15:12:31,469 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1)
Assign user to role Operators
2010-12-07 15:12:31,469 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1) User
'admin' authenticated, loginOk=true
2010-12-07 15:12:31,469 TRACE
[org.jboss.security.auth.spi.LdapExtLoginModule] (http-0.0.0.0-8080-1)
commit, loginOk=true
2010-12-07 15:12:31,469 ERROR [STDERR] (http-0.0.0.0-8080-1) 7.12.2010
15:12:31 com.example.facade.LoginFacade login
INFO: Subject retrieved: Subject:
    Principal: admin
    Principal: Roles(members:Operators,Admins)
2010-12-07 15:12:31,469 ERROR [STDERR] (http-0.0.0.0-8080-1) 7.12.2010
15:12:31 com.example.facade.LoginFacade login
INFO: Principal retrieved: admin
2010-12-07 15:12:31,469 ERROR [STDERR] (http-0.0.0.0-8080-1) 7.12.2010
15:12:31 com.example.facade.LoginFacade login
INFO: Principal retrieved: Roles(members:Operators,Admins)
2010-12-07 15:12:31,469 DEBUG
[org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase]
(http-0.0.0.0-8080-1) Couldn't handle invocation directly within
org.jboss.ejb3.proxy.handler.session.stateless.statelesslocalproxyinvocationhand...@393f3c:
Current invocation "public abstract void
com.example.facade.TestServiceLocal.testOperators()" is not eligible for
direct handling by
org.jboss.ejb3.proxy.handler.session.stateless.statelesslocalproxyinvocationhand...@393f3c
2010-12-07 15:12:31,469 DEBUG
[org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar]
(http-0.0.0.0-8080-1) Returning from name
"jboss.j2ee:ear=LDAPLoginTestFacade.ear,jar=LDAPLoginTestFacade-ejb.jar,name=TestService,service=EJB3":
jboss.j2ee:ear=LDAPLoginTestFacade.ear,jar=LDAPLoginTestFacade-ejb.jar,name=TestService,service=EJB3
2010-12-07 15:12:31,484 TRACE [org.jboss.security.SecurityRolesAssociation]
(http-0.0.0.0-8080-1) Setting threadlocal:{}
2010-12-07 15:12:31,484 TRACE
[org.jboss.security.plugins.authorization.JBossAuthorizationContext]
(http-0.0.0.0-8080-1) Control flag for
entry:org.jboss.security.authorization.config.AuthorizationModuleEntry{org.jboss.security.authorization.modules.DelegatingAuthorizationModule:{}REQUIRED}is:[REQUIRED]
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.authorization.modules.ejb.EJBPolicyModuleDelegate]
(http-0.0.0.0-8080-1) method=public void
com.example.facade.TestService.testOperators(), interface=Local,
requiredRoles=Roles(Operators,)
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.authorization.modules.ejb.EJBPolicyModuleDelegate]
(http-0.0.0.0-8080-1) Exception:Insufficient method permissions,
principal=null, ejbName=TestService, method=testOperators, interface=Local,
requiredRoles=Roles(Operators,), principalRoles=Roles()
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.plugins.authorization.JBossAuthorizationContext]
(http-0.0.0.0-8080-1) REQUIRED failed for
Name=org.jboss.security.authorization.modules.DelegatingAuthorizationModule:subject=Subject:
    Principal: anonymous
:role=Roles()
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.plugins.authorization.JBossAuthorizationContext]
(http-0.0.0.0-8080-1) Error in authorize:
org.jboss.security.authorization.AuthorizationException: Authorization
Failed:
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext.invokeAuthorize(JBossAuthorizationContext.java:263)
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext.access$000(JBossAuthorizationContext.java:67)
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext$1.run(JBossAuthorizationContext.java:152)
    at java.security.AccessController.doPrivileged(Native Method)
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext.authorize(JBossAuthorizationContext.java:148)
    at
org.jboss.security.plugins.JBossAuthorizationManager.internalAuthorization(JBossAuthorizationManager.java:474)
    at
org.jboss.security.plugins.JBossAuthorizationManager.authorize(JBossAuthorizationManager.java:124)
    at
org.jboss.security.plugins.javaee.EJBAuthorizationHelper.authorize(EJBAuthorizationHelper.java:116)
    at
org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke(RoleBasedAuthorizationInterceptorv2.java:189)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
    at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at
org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:219)
    at
org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
    at
org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
    at $Proxy135.testOperators(Unknown Source)
    at com.example.LoginServlet.testEJBmethods(LoginServlet.java:84)
    at com.example.LoginServlet.processRequest(LoginServlet.java:61)
...
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.plugins.javaee.EJBAuthorizationHelper]
(http-0.0.0.0-8080-1) Error in authorization:
org.jboss.security.authorization.AuthorizationException: Authorization
Failed:
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext.invokeAuthorize(JBossAuthorizationContext.java:263)
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext.access$000(JBossAuthorizationContext.java:67)
    at
org.jboss.security.plugins.authorization.JBossAuthorizationContext$1.run(JBossAuthorizationContext.java:152)
....
2010-12-07 15:12:31,500 TRACE
[org.jboss.security.audit.providers.LogAuditProvider] (http-0.0.0.0-8080-1)
[Error]Source=org.jboss.security.plugins.javaee.EJBAuthorizationHelper;Exception:=Authorization
Failed:
;Resource:=[org.jboss.security.authorization.resources.EJBResource:contextmap={policyregistration=org.jboss.security.plugins.jbosspolicyregistrat...@148b6d3}:method=public
void
com.example.facade.TestService.testOperators():ejbMethodInterface=Local:ejbName=TestService:ejbPrincipal=null:MethodRoles=Roles(Operators,):securityRoleReferences=null:callerSubject=Subject:
    Principal: anonymous
:callerRunAs=null:callerRunAs=null:ejbRestrictionEnforcement=false:ejbVersion=null];policyregistration=org.jboss.security.plugins.jbosspolicyregistrat...@148b6d3
;
2010-12-07 15:12:31,500 ERROR [com.example.LoginServlet]
(http-0.0.0.0-8080-1) testOperators access failed
javax.ejb.EJBAccessException: Caller unauthorized
2010-12-07 15:12:31,625 DEBUG
[org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase]
(http-0.0.0.0-8080-1) Couldn't handle invocation directly within
org.jboss.ejb3.proxy.handler.session.stateless.statelesslocalproxyinvocationhand...@393f3c:
Current invocation "public abstract void
com.example.facade.TestServiceLocal.testAdmins()" is not eligible for direct
handling by
org.jboss.ejb3.proxy.handler.session.stateless.statelesslocalproxyinvocationhand...@393f3c

Odpovedet emailem