Two Realm Authentication Issue

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Two Realm Authentication Issue

mmarino
This post was updated on .
I seem to be experiencing an issue with a two realm setup.

We have an LDAP Active Directory realm and a JDBC realm. The former we want to use for authentication and the latter for Authorization.

Here is the crux of the issue:

I have two separate classes, being called by two separate servlets. Later we will merge this into one class and one servlet, but for now we are trying to keep the two realms as separate as possible. Below are the examples of them ( I am keeping out error logging for the sake of brevity). I am using Glassfish 4, and if I restart the server and run the LDAP class, the LDAP class will work great and the JDBC one won't. The JDBC class will say that LDAP Authentication failed. If I then restart the Glassfish server and run JDBC class first, it will work great each time, but LDAP will not be able to find my user account. It seems whichever one I run first, the SecurityUtils or some part of shiro is remembering the first realm associated with it and logging the user against that one, regardless of what was set. So how do I get it to properly utilize the correct realm?

LDAP Class:

  public Boolean isAuthenticated(String Username, String Password){
        Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro2.ini");
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        System.out.println(Username);
        System.out.println(Password);
        UsernamePasswordToken token = new UsernamePasswordToken( Username, Password);
        Subject currentUser = SecurityUtils.getSubject();
        Boolean b = false;
        //Attempt login
        try{          
            currentUser.login(token);            
            b = currentUser.isAuthenticated();            
            currentUser.logout();
        }catch(Exception e){
   
        }

JDBC Class:

 public Boolean getPer(String un, String Permission){
            System.setProperty("log4j.category.org.apache.shiro", "DEBUG");          
            DataSource ds = null;
            try{
                Context ctx = new InitialContext();
                ds = (DataSource)ctx.lookup("jdbc/MyDataSource");
            }catch(Exception e){
               
            }
            Subject User = null;
            JdbcRealm realm = new org.apache.shiro.realm.jdbc.JdbcRealm();
           
            realm.setDataSource(ds);
            realm.setAuthenticationQuery("My query");
            realm.setUserRolesQuery("My query");
            realm.setPermissionsQuery("My query");
            realm.setPermissionsLookupEnabled(true);
           
            DefaultHashService hashService = new org.apache.shiro.crypto.hash.DefaultHashService();
            hashService.setHashIterations(500000);
            hashService.setHashAlgorithmName("SHA-256");
            hashService.setGeneratePublicSalt(true);
            hashService.setPrivateSalt(new SimpleByteSource("MySalt"));
            PasswordMatcher passwordMatcher = new org.apache.shiro.authc.credential.PasswordMatcher();
           
            DefaultPasswordService ps = new org.apache.shiro.authc.credential.DefaultPasswordService();
           
            passwordMatcher.setPasswordService(ps);
            realm.setCredentialsMatcher(passwordMatcher);
           
                       
            DefaultSecurityManager securityManager = new DefaultSecurityManager(realm);
            SecurityUtils.setSecurityManager(securityManager);

            Boolean b = false;
            UsernamePasswordToken token = null;
           
            try{
                User = SecurityUtils.getSubject();
                if (User == null || !User.isAuthenticated()) {

                    token = new UsernamePasswordToken(Username, Password);
                    User.login(token);
                }
                try {                        
                    if(User.isPermitted("Admin")){
                        b = true;
                    }else{
                        b = User.isPermitted(Permission);
                    }
         }catch(Exception e){
     }

Reply | Threaded
Open this post in threaded view
|

Re: Two Realm Authentication Issue

Brian Demers
I think there is a lot of context missing from this question.  You seem to be re-configuring shiro for each request?  

Take a look at one of the shiro web examples, and use a web.ini (or similar code).  If you have already done that can you add a some info about how your methods are getting called?

On Tue, Apr 11, 2017 at 4:38 PM, mmarino <[hidden email]> wrote:
I seem to be experiencing an issue with a two realm setup.

We have an LDAP Active Directory realm and a JDBC realm. The former we want
to use for authentication and the latter for Authorization.

Here is the crux of the issue:

I have two separate classes, being called by two separate servlets. Later we
will merge this into one class and one servlet, but for now we are trying to
keep the two realms as separate as possible. Below are the examples of them
( I am keeping out error logging for the sake of brevity). I am using
Glassfish 4, and if I restart the server and run the LDAP class, the LDAP
class will work great and the JDBC one won't. The JDBC class will say that
LDAP Authentication failed. If I then restart the Glassfish server and run
JDBC class first, it will work great each time, but LDAP will not be able to
find my user account. It seems whichever one I run first, the SecurityUtils
or some part of shiro is remembering the first realm associated with it and
logging the user against that one, regardless of what was set. So how do I
get it to properly utilize the correct realm?

LDAP Class:

  public Boolean isAuthenticated(String Username, String Password){
        Factory<org.apache.shiro.mgt.SecurityManager> factory = new
IniSecurityManagerFactory("classpath:shiro2.ini");
        org.apache.shiro.mgt.SecurityManager securityManager =
factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        System.out.println(Username);
        System.out.println(Password);
        UsernamePasswordToken token = new UsernamePasswordToken( Username,
Password);
        Subject currentUser = SecurityUtils.getSubject();
        Boolean b = false;
        //Attempt login
        try{
            currentUser.login(token);
            b = currentUser.isAuthenticated();
            currentUser.logout();
        }catch(Exception e){

        }

JDBC Class:

 public Boolean getPer(String un, String Permission){
            System.setProperty("log4j.category.org.apache.shiro", "DEBUG");
            DataSource ds = null;
            try{
                Context ctx = new InitialContext();
                ds = (DataSource)ctx.lookup("jdbc/MyDataSource");
            }catch(Exception e){

            }
            Subject User = null;
            JdbcRealm realm = new org.apache.shiro.realm.jdbc.JdbcRealm();

            realm.setDataSource(ds);
            realm.setAuthenticationQuery("My query");
            realm.setUserRolesQuery("My query");
            realm.setPermissionsQuery("My query");
            realm.setPermissionsLookupEnabled(true);

            DefaultHashService hashService = new
org.apache.shiro.crypto.hash.DefaultHashService();
            hashService.setHashIterations(500000);
            hashService.setHashAlgorithmName("SHA-256");
            hashService.setGeneratePublicSalt(true);
            hashService.setPrivateSalt(new SimpleByteSource("MySalt"));
            PasswordMatcher passwordMatcher = new
org.apache.shiro.authc.credential.PasswordMatcher();

            DefaultPasswordService ps = new
org.apache.shiro.authc.credential.DefaultPasswordService();

            passwordMatcher.setPasswordService(ps);
            realm.setCredentialsMatcher(passwordMatcher);


            DefaultSecurityManager securityManager = new
DefaultSecurityManager(realm);
            SecurityUtils.setSecurityManager(securityManager);

realm.getAuthorizationCache().remove(SecurityUtils.getSubject().getPrincipals());
            Boolean b = false;
            UsernamePasswordToken token = null;

            try{
                User = SecurityUtils.getSubject();
                if (User == null || !User.isAuthenticated()) {

                    token = new UsernamePasswordToken(Username, Password);
                    User.login(token);
                }
                try {
                    if(User.isPermitted("Admin")){
                        b = true;
                    }else{
                        b = User.isPermitted(Permission);
                    }
         }catch(Exception e){
     }





--
View this message in context: http://shiro-user.582556.n2.nabble.com/Two-Realm-Authentication-Issue-tp7581578.html
Sent from the Shiro User mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Two Realm Authentication Issue

mmarino
This post was updated on .
Some additional context:

I'm not using jsp files in the web portion, this is a three tier application so all of the user authentication is being handled by java application middle tier server. I'm sending the username and password over SSL using ajax.

The top function "isAuthenticated" already uses an ini file. I didn't include the ini file because the issue is how to switch (or reconfigure) the realms so that I can authenticate in one realm and authorize in another. Does that answer your question, or is there some other ini work I'm supposed to look at? Most of the examples I find online had different contexts than I currently have.

As for my methods, I'll do something like this:

   @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        DoAuth au = new DoAuth();
        Boolean b = au.isAuthorized("Username", "Password");
        if(b){
             if(au.isPer("PermissionName"){
                 //Do the thing you are authorized to do
             }

        }
       
    }