-
1. Re: JAAS Authentication from stand alone client
eefahs Aug 22, 2008 1:49 AM (in response to eefahs)No Help?
I think I have to explain more..
I have an already running application in weblogic and whose username, passowrd validation is done using jaas and all other role based autherisation checks are done programaatically and i want to port the application to JBoss. But in Jboss, it seems it support only declarative security and it always requires Roles.. Am I correct?
I have a bean which will do the username and password verification with db and from my login module I want to call this bean rather than configuring query with the login module.
Someone please respond.... -
2. Re: JAAS Authentication from stand alone client
ragavgomatam Aug 22, 2008 12:09 PM (in response to eefahs)HI
Quick answers :- Since it is java client
(1) You would be using a callback handler on the client to connect to your Jaas Module.
(2) Your CustomModule should be in a jar file under $HOME/server/default/lib
(3) The classpath in run.sh or run.bat of jboss should be changed to include your jar
(4) You would be useing an auth.config policy file as a part of your client start up & use this syntax, please check this out once again :-java -Djava.security.manager -Djava.security.auth.login.config==file:../conf/default/auth.conf
watch that ==.
(5) This auth.conf would be having the ClientLoginModule in addition to your module . The format should be as of a policy file.
(6) Use jars from $HOME/jboss/client in your client classpath. There are many jars from this directory, I don't immediately recall. However if using jdk 1.6 use classpath wildcard to use all the jars.
This should be good as a start. I will try to post more if this is insufficient -
3. Re: JAAS Authentication from stand alone client
eefahs Aug 25, 2008 4:59 AM (in response to eefahs)Hi,
Thank you very much for the response, I think I need more help..
Yes, I am using CallbackHandler.
I think I need to explain my requirement little bit more....
In my application initially it comes with a login screen and after user enters a username and password and presss login button it will create a LoginContext as follows
new LoginContext("myJaas", subject, new MyCallbackHandler(UserId, Password, serverUrl));
and then it will call loginContext.login()
And in my client side I have created a jaas.config file as follows
myJaas {
org.jboss.security.ClientLoginModule required;
com.my.security.jboss.db.DbLoginModuleImpl required debug=false authOnLogin=true;
};
SO it should internally call the login methods of each of these loginModules... (So For this we have to copy the LoginModule jar file to client side also right?)
and my DbLoginModuleImpl is as follows and the login method will just validate the useid and password with the database column values. If both exists in db, the method will return true. and the jaas authentication ends there...
Here is my LoginModule
final public class DbLoginModuleImpl implements LoginModule {
private Subject subject;
private CallbackHandler callbackHandler;
private boolean isloginSucceeded;
private boolean isprincipalsInSubject;
private boolean isException;
private ArrayList principalsForSubject = new ArrayList();
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
}
public boolean login() throws LoginException {
String userName = null;
String passwordHave = null;
String airlineCode = null;
Callback[] callbacks = getCallbacks();
String userValue = getUserName(callbacks);
userName = userValue;
if (userName.length() > 0) {
passwordHave = getPasswordHave(userName, callbacks);
}
if (validateUser(userName, passwordHave)) {
System.out.println("DbLoginModuleImpl.login() :: VALID USER");
SessionPrincipal sessionPrincipal = new SessionPrincipal(userName);
principalsForSubject.add(sessionPrincipal);
isloginSucceeded = true;
return true;
} else {
System.out.println("DbLoginModule.login() :: INVALID USER");
throw new FailedLoginException("Invalid User");
}
} catch (SystemException systemException) {
throw new FailedLoginException(systemException.getErrorCode());
}
} finally {
System.out.println("DbLoginModule exiting login()");
}
}
public boolean commit() throws LoginException {
if (isloginSucceeded) {
subject.getPrincipals().addAll(principalsForSubject);
subject.getPublicCredentials().addAll(principalsForSubject);
subject.getPrivateCredentials().addAll(principalsForSubject);
isprincipalsInSubject = true;
return true;
} else {
return false;
}
}
public boolean abort() throws LoginException {
if (isprincipalsInSubject) {
subject.getPrincipals().removeAll(principalsForSubject);
isprincipalsInSubject = false;
}
return true;
}
public boolean logout() throws LoginException {
return true;
}
}
But the problem with JBOSS is that, it will not execute the login method immediately when we called the logincontext.login() Am I correct?
It will execute it only when we try to execute method on a EJB for which we define a <security-domain>java:/jaas/myJaas</security-domain>. Also for that EJB we have to declare <security-role-ref> attribute with the required roles.
And in my case i dont have a role, if the LoginModule.login method validates the username and password successfully, it should be allowed to execute the above bean method also... how can I achieve this?
Basically, I just want to validate the username and password with the JAAS authentication no roles nothing...
Help me.. -
4. Re: JAAS Authentication from stand alone client
ragavgomatam Aug 25, 2008 10:44 AM (in response to eefahs)2 issues here. Lets take the first one. You will have to change your login module to extend jboss AbstractServerLoginModule as follows :-
Here is my LoginModule
final public class DbLoginModuleImpl implements LoginModule {
tofinal public class DbLoginModuleImpl implements AbstractServerLoginModule {
There is a posting for this whole code somewhere earlier in this forum, on how to extend this jboss AbstractServerLoginModule & do a database authentication.
Second issue :- You cannot use a JAAS module only for authentication. JAAS stands for Authentication & Authorization. So as a part of logging in you will have to authenticate & also provide roles. These roles are then used by container in conjunction with j2ee artifacts (web.xml & ejb-jar.xml) to provide role based declarative authorization.This whole process is intimately tied with Roles in j2ee security architecture. Thats why you haverole
elements in web.xml and ejb-jar.xml.
If, however you want to provide default Roles, then go ahead, provide default roles & use these in your module and the web.xml and ejb-jar.xml. However you WILL have to provide roles. -
5. Re: JAAS Authentication from stand alone client
eefahs Aug 26, 2008 2:15 AM (in response to eefahs)Hi Ragav,
Thanks for the reply and Now I changed my LoginModule based on your reply. and decided to go with a default role for all users.
And I have created a jar file for my loginmodule and copied it to
server\{myDomain}\lib folder and when I tried to run the client I am getting the following exception in the server.log
**********************************************************
2008-08-26 10:14:07,811 TRACE [org.jboss.security.SecurityAssociation] getPrincipal, principal=MASTER#V1
2008-08-26 10:14:07,811 TRACE [org.jboss.security.plugins.JaasSecurityManager.myJaas] Begin isValid, principal:MASTER#V1, cache info: null
2008-08-26 10:14:07,811 TRACE [org.jboss.security.plugins.JaasSecurityManager.myJaas] defaultLogin, principal=MASTER#V1
2008-08-26 10:14:07,811 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] Begin getAppConfigurationEntry(myJaas), size=9
2008-08-26 10:14:07,811 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] End getAppConfigurationEntry(myJaas), authInfo=AppConfigurationEntry[]:
[0]
LoginModule Class: com.jboss.db.MyLoginModuleImpl
ControlFlag: LoginModuleControlFlag: required
Options:
2008-08-26 10:14:07,811 ERROR [org.jboss.ejb.plugins.LogInterceptor] Unexpected Error in method: public abstract com.security.controller.SecurityController com.security.controller.SecurityControllerHome.create() throws javax.ejb.CreateException,java.rmi.RemoteException
java.lang.NoClassDefFoundError: org/jboss/security/auth/spi/AbstractServerLoginModule at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassLocally(RepositoryClassLoader.java:200)
at org.jboss.mx.loading.ClassLoadingTask$ThreadTask.run(ClassLoadingTask.java:131)
at org.jboss.mx.loading.LoadMgr3.nextTask(LoadMgr3.java:399)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:527)
at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:92)
at org.jboss.mx.loading.LoaderRepositoryClassLoader.loadClass(LoaderRepositoryClassLoader.java:90)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at org.jboss.util.loading.DelegatingClassLoader.loadClass(DelegatingClassLoader.java:92)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:731)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:603)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:537)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:344)
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:211)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:135)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:637)
at org.jboss.ejb.Container.invoke(Container.java:981)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:169)
at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:118)
at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:209)
at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:195)
at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:184)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
at $Proxy654.create(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
**********************************************************
1) Why NoClassDefFoundError: org/jboss/security/auth/spi/AbstractServerLoginModule Error? do I have to bundle jbosssx.jar with my loginmodule jarfile? Why it is not taking from the same folder? I tried by giving ClassPath entry in METAINF file also.
2) Do I have to copy my loginmodule jar file to the clients classpath?
Tanks in advance -
6. Re: JAAS Authentication from stand alone client
eefahs Aug 26, 2008 8:28 AM (in response to eefahs)Hi,
With some changes atlast the call reached my LoginModule. Thanks for your help. But
How can I access an ejb which resides in another ear file from My LoginModule? For validating my user I want to use an existing EJB method call.
EJB is deployed as an application and MyLoginModule jar file is kept in the server/[mmyconf]/lib folder -
7. Re: JAAS Authentication from stand alone client
ragavgomatam Aug 26, 2008 6:54 PM (in response to eefahs)How can I access an ejb which resides in another ear file from My LoginModule? For validating my user I want to use an existing EJB method call.
Wouldn't that be a re-entrant call ? You are trying to secure a resource, but as a part of the login, you are trying to access the resource you are trying to protect !!!! It will be a circularity. To solve this , cut the ejb out of the picture from the LoginModule & use a simple, straight database call. Once authenticated, ejb's are protected by this Principal. Also LoginModule is for the entire server, not a particular EAR -
8. Re: JAAS Authentication from stand alone client
eefahs Sep 2, 2008 4:18 AM (in response to eefahs)Hi,
Thanks for the reply and Now I changed my LoginModule to remove the ejb call and ti works perfectly . again few more clarifications will be helpfull
I have deployed my application as a folder, which contains multiple jar files. and I have specified <security-domain> for only one jar that is security.jar. Now the authentication is successfull and my commit method looks like belowpublic boolean commit() throws LoginException { if (isloginSucceeded) { try{ Set principals = subject.getPrincipals(); principals.add(principal); Group[] roleSets = getRoleSets(); for(int g = 0; g < roleSets.length; g ++) { Group group = roleSets[g]; String name = group.getName(); Group subjectGroup = createGroup(name, principals); if( subjectGroup instanceof NestableGroup ) { SimpleGroup tmp = new SimpleGroup("Roles"); subjectGroup.addMember(tmp); subjectGroup = tmp; } Enumeration members = group.members(); while( members.hasMoreElements() ) { Principal role = (Principal) members.nextElement(); subjectGroup.addMember(role); } } isprincipalsInSubject = true; }catch(Exception e){ e.printStackTrace(); } return true; } else { return false; } }
Now, I want to lookup a ejb of my security.jar from another jar file. I added correct <security-role-ref> entries but I am getting the error asCaused by: javax.security.auth.login.LoginException: Username not supplied.
at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.throwLoginException(JDbLoginModuleImpl.java:322)
at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.getUserName(JDbLoginModuleImpl.java:368)
at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.login(JDbLoginModuleImpl.java:164)
So it is again calling CallBackHandler for getting the username and password. How can I avoid this? How can I cache the Callback details.
Thanks in advance -
9. Re: JAAS Authentication from stand alone client
eefahs Sep 3, 2008 7:24 AM (in response to eefahs)More details..
My application is devided into different subsystems and each subsystem is a different jar.
and one of my jar is defined with a security domain and the initial call to this subsystem triggered the login method and it was successfull and user logged into the system.
And the same user was accessing an ejb from another subsystem which was internally refering the subsystem with security domain defined. again the login method triggered (why is it every call need a login call?) and it was trying to get the username, ofcourse it was null and the call failed.
I tried by defining the role security-role-ref for the calling subsystem ejb, but it fails in the login.. How to handle this situation?
Thanks in advance -
10. Re: JAAS Authentication from stand alone client
ragavgomatam Sep 3, 2008 3:47 PM (in response to eefahs)Are you using a java client ?
How is this done ?And the same user was accessing an ejb from another subsystem
Point is, if you using a java client then Authentication is per login. Which means , you login from your java client, access the secured ejb, do your work & log out. If you call a unsecured subsystem, then login has to happen before access is granted to the secured resource.
Hope this explains -
11. Re: JAAS Authentication from stand alone client
eefahs Sep 3, 2008 11:52 PM (in response to eefahs)Hi ragav,
Yes I am using a java client, yes first the user will login to the system by accessing the secured subsystem and after that he can access any other subsystem without any authentication, that is my requirement.
But, after successfull login when the user trying to use a unsecured subsystem and an ejb from this unsecured subsystem wants to access a ejb from the secured subsystem the call fails with the errorCaused by: javax.security.auth.login.LoginException: Username not supplied. at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.throwLoginException(JDbLoginModuleImpl.java:322) at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.getUserName(JDbLoginModuleImpl.java:368) at com.ibsplc.iRes.security.jboss.db.JDbLoginModuleImpl.login(JDbLoginModuleImpl.java:164)
user - accessing secured ejb - internall calls LoginModule.login() login successfull
- accessiing unsecured ejb - successfull
- accessing a unsecured ejb, which calls secured ejb - failes
So how this unsecured ejb can be enabled to call a secured ejb? I tried by defining the appropriate security-role-ref for the unsecured ejb also. But again the call from unsecured subsystem to the secured subsystem triggers the LoginModule.login() and the username is null;
Is something wrong in my logic? -
12. Re: JAAS Authentication from stand alone client
ragavgomatam Sep 4, 2008 10:52 AM (in response to eefahs)user - accessing secured ejb - internall calls LoginModule.login() login successfull
- accessiing unsecured ejb - successfull
- accessing a unsecured ejb, which calls secured ejb - failes
Post the code that does this -
13. Re: JAAS Authentication from stand alone client
ragavgomatam Sep 4, 2008 10:54 AM (in response to eefahs)Also I think here is where the problem lies
- accessing a unsecured ejb, which calls secured ejb - failes
Where is the jaas login done before you access a secured ejb ? -
14. Re: JAAS Authentication from stand alone client
eefahs Sep 8, 2008 7:47 AM (in response to eefahs)Hi ragav,
While starting up my java client, it will ask for a username and password and entring the username and password, when the user enters the submit(login) button, it will create LoginContext and will call logon and then try to call the secured ejb and then will cal a unsecured ejb for logon auditing purpose... so all the calls will trigger from the single logon button click.Class homeClass = getEJBHomeClass(serviceName); context = (InitialContext) getNewInitialContext(serverName); EJBHome ejbHome = (EJBHome) context.lookup(ejbService.getJndiName()); obj = PortableRemoteObject.narrow(ejbHome, homeClass); ejbObject = (EJBObject) obj.create();
Above is the details of the call to the server. After login when we call the secured ejb, it will trigger the login and the login is successfull and the call to the secured ejb is also successfull. So aftre both these calls, server itself will create a jms message for audit and it will put in a queue and an MDB will pick the message and for processign this message MDB will try to call the secured EJB, then the problem comes... it is saying that the username is null so login failed and so the call will fail.
hope the flow is clear now
what should i do now?