Hi Viktar

In JAAS authentication is performed using login modules.
An application using JAAS (application server or not) is using a model of let say Security Domains identified by an unique name and that are guarded by at least one Login Module. When you log into a security domain the credentials you are passing are transmitted to its login modules to perform authentication. When you log in you must provide a security domain. This way the corresponding
login modules can be located (if any was registered of course).
Login modules inside a security domain are located and the credentials are passed to them for authentication (but not necessarily - these login modules may do anything you want ... for example you may write a login module only for audit reasons).

When writing beans you can protect accesses to these beans using a security domain. For example you can specify that accesses to the DocumentManagerBean bean must be authenticated against the "nuxeo-ecm" security domain . This means all accesses to DocumentManagerBean are checked against the login modules defined by the "nuxeo-ecm" security domain. This module can use SQL based directories (a custom impl. through JDBC) or LDAP directories.

So what I understand is that you use a LDAP directory to authenticate your users. But when calling beans from nuxeo the nuxeo application fails to authenticate them
(even if the user were authenticated at your application level)
If this is the problem - I think the response is simple:

When you authenticate through JAAS the user is not authenticated against the nuxeo security domain but against your security domain. Even if JBoss is preserving on the current thread the authentication info when trying to access a nuxeo bean this authentication info will be validated against the nuxeo security domain - this means the nuxeo user directory (that can be a RDBMS or a LDAP one) and the authentication will fail since your identity doesn't exist in nuxeo user directory but only in your directory.

You need to share the LDAP directory with nuxeo and it will work.
How to do this ask on the list because personally I don't know :)

Regards,
Bogdan


Viktar Duzh wrote:
Hi Bogdan,

I'll give you an example:

My Web app uses JAAS to perform authentication (via LDAP in fact). Consequently, I don't have the password that a user entered. So, there is no way to pass all the credentials on to Nuxeo.

It is normal scenario when you integrate enterprise level systems.

Any thoughts how to resolve this issue?

Regards,

-- Viktar

----- Original Message ----- From: "Bogdan Stefanescu" <[EMAIL PROTECTED]>
To: "Filipchik Alexander" <[EMAIL PROTECTED]>
Cc: "'Nuxeo List'" <[email protected]>
Sent: Tuesday, August 07, 2007 2:24 PM
Subject: Re: [Ecm] Nuxeo security system and Remoting



It's weird that you login only one time.
Normally you should login on each request otherwise it is not working.
We already have this problem on our web service implementation
At each web service call we perform a login - without this it's not working.

Can you send me a simple example that can be used to reproduce this?

Bogdan

P.S.
It is recommended to use RepositoryManager to open a session and not directly
by calling

CoreInstance.getInstance().open(repository,null)

So the recommended way is to do:

RepositoryManager mgr = Framework.getService(RepositoryManager.class);
               Repository repo = mgr.getRepository(repositoryName);
               session = repo.open();

or if you have a single repopsitory

RepositoryManager mgr = Framework.getService(RepositoryManager.class);
               Repository repo = mgr.getDefaultRepository();
               session = repo.open();


Do not forget to close your session when you are no more using it by calling

CoreInstance.getInstance().close(session);


In future the close method will be available on the repository itself.
For now you need to use

CoreInstance.getInstance()

to close it but in future the CoreInstance class will be removbed from the API and will be an implementation detail.

Bogdan


Filipchik Alexander wrote:
Thank. I'll try to implement this approach in my app.

But: why does my current approach work?
Now I execute Framework.login() one time, when my web-application (tomcat) starts. Then, when requests are coming on server-side I simple execute -
CoreInstance.getInstance().open(repository,null);

Every request is executed in own thread. But it not causes security errors.
Why? (Framework.logout I call when web-app is shutting down)

Alexander.

-----Original Message-----
From: Bogdan Stefanescu [mailto:[EMAIL PROTECTED] Sent: Tuesday, August 07, 2007 1:39 PM
To: Filipchik Alexander
Cc: 'Nuxeo List'
Subject: Re: [Ecm] Nuxeo security system and Remoting

Filipchik Alexander wrote:

Hello friends.
Now I am investigating your security approach connected to Nuxeo-Remote framework. I found, that interaction with remote Nuxeo server starts with calling an Framework.login(username, userpassword).
What is confusing me - it's an static methods.
After I had login in  I can create sessions by
CoreInstance.getInstance().open(repository, null).
It's another static method.
Yes they are static - but there is nothing wrong with that.
They act as a facade to simplify API - but inside they call non static methods.
For example
Framework.login(username, password);
is a shortcut for

Framework.getRuntime().getService(LoginService.class).login(username, password);
or .. this is the same as
Framework.getLocalService(LoginService.class).login(username, password);

and LoginService.login(...) is not static.

This method is finally calling

        LoginContext ctx = new LoginContext(name, handler);
        ctx.login();

which is part of java.security API.

There is nothing wrong with being static or not.


Its means that I can't create sessions for several users in one time.

You can but in a thread you can have only one login context at a time.
So if you want to use several logins you need to logout first and then re-login using a different account Or you may also use different threads each one using its own login context.

The problem is that after you logout you need to refetch a new CoreSession (because the core session you already have was created in the old login context and you need the new core session to be validated in the new context)

We already have this working in Apogee (Apogee is a nuxeo ECM rich client based on Eclipse RCP) I am currently working on simplifying client environment and connection configuration. You can take a look at this project to see examples or to reuse some modules.


I will explain here how the login is done on the client side to make things clear for everyone:

To login through a javax.security.auth.LoginContext you need to call:

LoginContext lc = Framework.login(username, password);

This will use lookup right LoginModule to login on Nuxeo ECM server and will use that module
to perform the login, then it returns the login context:

The login is done as follow:

    public LoginContext login(String username, Object credentials)
            throws LoginException {
DefaultCallbackHandler handler = new DefaultCallbackHandler(username,
                credentials);
        LoginContext ctx = new LoginContext(name, handler);
        ctx.login();
        return ctx;
    }

Later you can logout using the renturned context:
lc.logout();

Now, what exactly happens after the login method is called?

        LoginContext ctx = new LoginContext(name, handler);
        ctx.login();

This is explained in LoginContext javadoc.

The login configuration will be queried about the login module registered for the specified security domain (the name argument) and then the registered login module will be used to perform the login using the passed credentials.

In our case the security domain name is "nuxeo-client-login" and the login module registered for this domain
is
org.jboss.security.ClientLoginModule

So finally the Framework.login(username, password) method will end up in calling the methods

org.jboss.security.ClientLoginModule.login()
and then
org.jboss.security.ClientLoginModule.commit()

This is performing the login specific to a JBoss client

If you look into the code in org.jboss.security.ClientLoginModule you will se that jboss is doing the login as follows:

   public static void pushSubjectContext(Subject subject,
      Principal principal, Object credential)
   {
      SecurityManager sm = System.getSecurityManager();
      if (sm != null)
         sm.checkPermission(setPrincipalInfoPermission);

      // Set the legacy single-value access points
      if (server)
      {
         threadPrincipal.set(principal);
         threadCredential.set(credential);
      }
      else
      {
         SecurityAssociation.principal = principal;
         SecurityAssociation.credential = credential;
      }
      // Push the subject context
SubjectContext sc = new SubjectContext(subject, principal, credential);
      threadSubjectStacks.push(sc);
      if (trace)
log.trace("pushSubjectContext, subject=" + subject + ", sc="+sc);
   }

where threadPrincipal and threadCredential are thread local variable.


What means all this?

It means that in fact when you perform a Framework.login(username, password) the login context (username and credentials) are pushed in a thread local stack attached to the current thread and the first time you will access a protected bean remotely JBoss will use the information available in this stack
(by doing a stack.peek).
So the real login (authentication) on the server side is made when you first access a protected bean and not when you call the login method.

This also means that the login is valid only in the current thread - so if you are using mutliple threads you need to do for each one a new login. This also means that you can perform several login in a thread to switch the identity and the restore the old login using a logout (which will pop the current login from the local thread stack).
LoginContext lc1 = Framework.login("u1", "p1");
//... do something
LoginContext lc2 = Framework.login("u2", "p2");
// .. do domething
lc2.logout();
// now we are back in the lc1 context
lc1.logout();
// now we are no more logged in

Note that I have *not* tested this but theoretically it should work.

This also means the login itself is not costly -> it initialize only a thread local variable and the authentication on the server side is done later when you access a protected bean.

I hope this will clarify how login works.
If you have more question do not hesitate

Regards,
Bogdan




In my test integration application I create next approach:

1) When my web-app is starting - I init Nuxeo-Remoting (Framework,..) and

do

login as Administrator.
2) I add and delete documents
3) When I shoot down application - I do logout.
But in this way - I interact with Nuxeo only under Administrator user.


How will I have to change it, to allow permission management on Nuxeo

side?

For example:
1) I add login page into my application
2) When app is starting - I init Nuxeo-remote
3) When I need to add or delete document - I do Framework.login (using
current user credentials), getSession, logout (all in synchronize

section).

Is it right way? If yes - is it good for performance? Can I create an holder, that can holds session factory each loggined user

to

avoid login/logout actions on each remote call and multi threading

killing?

Alexander

_______________________________________________
ECM mailing list
[email protected]





_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm



_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm

Reply via email to