You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Datta <ma...@yahoo.com> on 2011/02/17 14:53:04 UTC

Help with configuring mulitple ActiveDirectory in web app

Hello Friends: 
I am trying to use Active Directory Realm in my web application 
I have to authenticate users against 2 Active Directory 
Need help with configuration? 

Questions: 
1. First when the form is submitted, request does not reach LoginUser
servlet? (Unable to figure out whats wrong with .ini) 
After disabling filter, request reaches Servlet, but realms are not
available.:( 
2. How do I know which realm is used by LoginUser servlet? 
3. Where do I specifiy so that these realms are available to
SecurityManager/DefaultWebSecurityManager? 
4. I tried the example here 
http://www.ibm.com/developerworks/web/library/wa-apacheshiro/
It works well but with only 1 realm 


Below is my shiro.ini, login.jsp, web.xml, login servlets doPost Method 
[main] 
sirRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm 
sirRealm.systemUsername = xxxx 
sirRealm.systemPassword = xxx 
sirRealm.searchBase = OU=IT,OU=MA-Users,DC=cinfotec,DC=corp 
sirRealm.url = ldap://ad0.cinfotec.corp:389/ 

xmrRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm 
xmrRealm.systemUsername = xxxx 
xmrRealm.systemPassword = xxx 
xmrRealm.searchBase = OU=BU,OU=MA-Users,DC=cinfotec,DC=corp 
xmrRealm.url = ldap://ad1.cinfotec.corp:389/ 

authc.loginUrl = /login.jsp 
[urls] 
# make sure the end-user is authenticated.  If not, redirect to the
'authc.loginUrl' above, 
# and after successful authentication, redirect them back to the original
account page they 
# were trying to view: 
/** = authc 
--------------------------------------------------------------- 
login.jsp 
<form name="loginform" method="post" action='LoginUser'> 
    <table align="left" border="0" cellspacing="0" cellpadding="3"> 
        <tr> 
            <td>Username:</td> 
            <td><input type="text" name="username" maxlength="30"></td> 
        </tr> 
        <tr> 
            <td>Password:</td> 
            <td><input type="password" name="password" maxlength="30"></td> 
        </tr> 
        <tr> 
            <td colspan="2" align="left"><input type="checkbox"
name="rememberMe">Remember Me</td> 
        </tr> 
        <tr> 
            <td colspan="2" align="right"><input type="submit" name="submit"
value="Login"></td> 
        </tr> 
    </table> 
</form> 
--------------------------------------------------------------- 
web.xml 
    <filter> 
        <filter-name>ShiroFilter</filter-name> 
       
<filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>ShiroFilter</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <servlet> 
        <servlet-name>LoginUser</servlet-name> 
        <display-name>LoginUser</display-name> 
        <description>Servlet to autenticate User agains AD</description> 
        <servlet-class>com.siriusxm.security.Login</servlet-class> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name>LoginUser</servlet-name> 
        <url-pattern>/LoginUser</url-pattern> 
    </servlet-mapping> 

--------------------------------------------------------------- 
LoginUser Servlet doPost 

    public void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException { 
        String url = "/login.jsp"; // Get the login page url fromm
properties file 
        String username = request.getParameter("username"); 
        String password = request.getParameter("password"); 
        UsernamePasswordToken token = 
                new UsernamePasswordToken(username, password); 

        try { 
        Subject subject = SecurityUtils.getSubject(); 
        subject.login(token); 
        //token.clear(); 
        url = "/secure/index.jsp"; 

        } catch (AuthenticationException e) { 
            logger.error("Error:" + e.getMessage()); 
            e.printStackTrace(); 
        } 
        RequestDispatcher dispatcher = 
             getServletContext().getRequestDispatcher(url); 
        
        dispatcher.forward(request, response);   

        }
-- 
View this message in context: http://shiro-user.582556.n2.nabble.com/Help-with-configuring-mulitple-ActiveDirectory-in-web-app-tp6035984p6035984.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Help with configuring mulitple ActiveDirectory in web app

Posted by Datta <ma...@yahoo.com>.
Hello Liz: Thanks for the response, 
I initially tried instantiating creating securityManager as below

        DefaultWebSecurityManager securityManager = new
DefaultWebSecurityManager();

        securityManager.setRealms(getAllADRealms());

        securityManager.setSessionManager(new DefaultWebSessionManager());

       
//securityManager.setSessionMode(DefaultWebSecurityManager.HTTP_SESSION_MODE);

       
securityManager.setSessionMode(DefaultWebSecurityManager.NATIVE_SESSION_MODE);

        securityManager.setSubjectFactory(new DefaultWebSubjectFactory());

        securityManager.setRememberMeManager(new CookieRememberMeManager());
 
But looks like there more to it 
So changed my code to use PassThruAuthenticationFilter via configuration in
shiro.ini

Now login works perfectly:
Question regarding Logout:When the user session expires I am logging out
user as follows
or when the user clicks Logout, I invalidate session and this method gets
called.

for e.g.
    public void sessionDestroyed(HttpSessionEvent se) {
        logger.debug("sessionDestroyed: due to  Logout or session Expired");
        Subject userinsession = (Subject)
se.getSession().getAttribute("user");

        try {
            if (SecurityUtils.getSecurityManager() != null) {
                Subject user = SecurityUtils.getSubject();
                if (user != null) { // This is never null
                    logger.debug("sessionDestroyed: logging out user via
Security Utils");
                    user.logout();
                }
            }
        } catch (UnavailableSecurityManagerException e) {
            logger.error("Security Manager not Available:", e);
            e.printStackTrace();
        }
    }

I see the exception below
Security Manager not Available:
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager
accessible to the calling code, either bound to the
org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an
invalid application configuration.
        at
org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123) 

Not sure what is wrong and why am i getting this exception

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Help-with-configuring-mulitple-ActiveDirectory-in-web-app-tp6035984p6231615.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Help with configuring mulitple ActiveDirectory in web app

Posted by Les Hazlewood <lh...@apache.org>.
Oh, one final note.  Your form action URL should be the same as your
filter's 'loginUrl':

<form name="loginform" method="post" action='${authc.loginUrl}'>
...

where ${authc.loginUrl] is the same value as configured on the authc
filter in the ini [main] section.

Also, you should probably look at Shiro's sample web application, as
it shows a working example:
http://svn.apache.org/repos/asf/shiro/trunk/samples/

particularly the 'web' module.

Cheers,

Les

On Thu, Feb 17, 2011 at 11:28 AM, Les Hazlewood <lh...@apache.org> wrote:
> Hi Datta,
>
> Assuming your INI config is in a file named shiro.ini at the root of
> the classpath, then you've configured the ShiroFilter correctly in
> web.xml.  Your realm definitions look fine - Shiro will automatically
> find all realms defined in shiro.ini and set them on the
> SecurityManager.  If you want to be explicit, you can configure them
> explicitly:
>
> [main]
> realm1 = ...
> realm2 = ..
> securityManager.realms = $realm1, $realm2
>
> You can read more about INI/object-graph configuration here:
> http://shiro.apache.org/configuration.html
>
> The reason your request does not reach your LoginUser servlet is
> because the 'authc' filter is a
> org.apache.shiro.web.filter.authc.FormAuthenticationFilter instance.
> It will process your logins automatically and redirect users as needed
> based on your configuration.  This means the POST request will always
> be handled by the FormAuthenticationFilter and will never be allowed
> to 'fall through' to a controller or servlet below it.  When using the
> default FormAuthenticationFilter, there is no need for a servlet or
> controller.  All you need to do is configure your application's login
> url (where your form is located).
>
> For example:
>
> [main]
> # define your 2 realms here
> ...
> authc.loginUrl = /login.jsp
>
> If you _don't_ want the FormAuthenticationFilter to process your login
> POST requests, and instead you want to let the requests pass through
> to a servlet or MVC controller, you'll want to redefine the 'authc'
> filter to be a org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
> instance instead:
>
> [main]
> # realms
> authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
> authc.loginUrl = /login.jsp
>
> The FormAuthenticationFilter is easiest to use, but the
> PasThruAuthenticationFilter is useful if you need to do additional
> request processing beyond a standard login.  See the
> FormAuthenticationFilter and the PassThruAuthenticationFilter JavaDoc
> for more information.
>
> Finally, when multiple realms are configured, Shiro's default
> authentication strategy is to call each realm.  As long as at least
> one of those realms authenticates successfully, the authentication
> will be successful.  You can see this happen by using your debugger
> and putting a breakpoint in the
> org.apache.shiro.authc.pam.ModularRealmAuthenticator class's
> 'doAuthenticate' method.  You can change the strategy if you want to
> as well (AllSuccessfulStrategy, FirstSuccessfulStrategy, etc - see the
> ModularRealmAuthenticator JavaDoc for more).
>
> HTH,
>
> --
> Les Hazlewood
> Founder, Katasoft, Inc.
> Application Security Products & Professional Apache Shiro Support and Training:
> http://www.katasoft.com
>
> On Thu, Feb 17, 2011 at 5:53 AM, Datta <ma...@yahoo.com> wrote:
>>
>> Hello Friends:
>> I am trying to use Active Directory Realm in my web application
>> I have to authenticate users against 2 Active Directory
>> Need help with configuration?
>>
>> Questions:
>> 1. First when the form is submitted, request does not reach LoginUser
>> servlet? (Unable to figure out whats wrong with .ini)
>> After disabling filter, request reaches Servlet, but realms are not
>> available.:(
>> 2. How do I know which realm is used by LoginUser servlet?
>> 3. Where do I specifiy so that these realms are available to
>> SecurityManager/DefaultWebSecurityManager?
>> 4. I tried the example here
>> http://www.ibm.com/developerworks/web/library/wa-apacheshiro/
>> It works well but with only 1 realm
>>
>>
>> Below is my shiro.ini, login.jsp, web.xml, login servlets doPost Method
>> [main]
>> sirRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
>> sirRealm.systemUsername = xxxx
>> sirRealm.systemPassword = xxx
>> sirRealm.searchBase = OU=IT,OU=MA-Users,DC=cinfotec,DC=corp
>> sirRealm.url = ldap://ad0.cinfotec.corp:389/
>>
>> xmrRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
>> xmrRealm.systemUsername = xxxx
>> xmrRealm.systemPassword = xxx
>> xmrRealm.searchBase = OU=BU,OU=MA-Users,DC=cinfotec,DC=corp
>> xmrRealm.url = ldap://ad1.cinfotec.corp:389/
>>
>> authc.loginUrl = /login.jsp
>> [urls]
>> # make sure the end-user is authenticated.  If not, redirect to the
>> 'authc.loginUrl' above,
>> # and after successful authentication, redirect them back to the original
>> account page they
>> # were trying to view:
>> /** = authc
>> ---------------------------------------------------------------
>> login.jsp
>> <form name="loginform" method="post" action='LoginUser'>
>>    <table align="left" border="0" cellspacing="0" cellpadding="3">
>>        <tr>
>>            <td>Username:</td>
>>            <td><input type="text" name="username" maxlength="30"></td>
>>        </tr>
>>        <tr>
>>            <td>Password:</td>
>>            <td><input type="password" name="password" maxlength="30"></td>
>>        </tr>
>>        <tr>
>>            <td colspan="2" align="left"><input type="checkbox"
>> name="rememberMe">Remember Me</td>
>>        </tr>
>>        <tr>
>>            <td colspan="2" align="right"><input type="submit" name="submit"
>> value="Login"></td>
>>        </tr>
>>    </table>
>> </form>
>> ---------------------------------------------------------------
>> web.xml
>>    <filter>
>>        <filter-name>ShiroFilter</filter-name>
>>
>> <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
>>    </filter>
>>    <filter-mapping>
>>        <filter-name>ShiroFilter</filter-name>
>>        <url-pattern>/*</url-pattern>
>>    </filter-mapping>
>>
>>    <servlet>
>>        <servlet-name>LoginUser</servlet-name>
>>        <display-name>LoginUser</display-name>
>>        <description>Servlet to autenticate User agains AD</description>
>>        <servlet-class>com.siriusxm.security.Login</servlet-class>
>>    </servlet>
>>    <servlet-mapping>
>>        <servlet-name>LoginUser</servlet-name>
>>        <url-pattern>/LoginUser</url-pattern>
>>    </servlet-mapping>
>>
>> ---------------------------------------------------------------
>> LoginUser Servlet doPost
>>
>>    public void doPost(HttpServletRequest request, HttpServletResponse
>> response) throws ServletException, IOException {
>>        String url = "/login.jsp"; // Get the login page url fromm
>> properties file
>>        String username = request.getParameter("username");
>>        String password = request.getParameter("password");
>>        UsernamePasswordToken token =
>>                new UsernamePasswordToken(username, password);
>>
>>        try {
>>        Subject subject = SecurityUtils.getSubject();
>>        subject.login(token);
>>        //token.clear();
>>        url = "/secure/index.jsp";
>>
>>        } catch (AuthenticationException e) {
>>            logger.error("Error:" + e.getMessage());
>>            e.printStackTrace();
>>        }
>>        RequestDispatcher dispatcher =
>>             getServletContext().getRequestDispatcher(url);
>>
>>        dispatcher.forward(request, response);
>>
>>        }
>> --
>> View this message in context: http://shiro-user.582556.n2.nabble.com/Help-with-configuring-mulitple-ActiveDirectory-in-web-app-tp6035984p6035984.html
>> Sent from the Shiro User mailing list archive at Nabble.com.

Re: Help with configuring mulitple ActiveDirectory in web app

Posted by Les Hazlewood <lh...@apache.org>.
Hi Datta,

Assuming your INI config is in a file named shiro.ini at the root of
the classpath, then you've configured the ShiroFilter correctly in
web.xml.  Your realm definitions look fine - Shiro will automatically
find all realms defined in shiro.ini and set them on the
SecurityManager.  If you want to be explicit, you can configure them
explicitly:

[main]
realm1 = ...
realm2 = ..
securityManager.realms = $realm1, $realm2

You can read more about INI/object-graph configuration here:
http://shiro.apache.org/configuration.html

The reason your request does not reach your LoginUser servlet is
because the 'authc' filter is a
org.apache.shiro.web.filter.authc.FormAuthenticationFilter instance.
It will process your logins automatically and redirect users as needed
based on your configuration.  This means the POST request will always
be handled by the FormAuthenticationFilter and will never be allowed
to 'fall through' to a controller or servlet below it.  When using the
default FormAuthenticationFilter, there is no need for a servlet or
controller.  All you need to do is configure your application's login
url (where your form is located).

For example:

[main]
# define your 2 realms here
...
authc.loginUrl = /login.jsp

If you _don't_ want the FormAuthenticationFilter to process your login
POST requests, and instead you want to let the requests pass through
to a servlet or MVC controller, you'll want to redefine the 'authc'
filter to be a org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
instance instead:

[main]
# realms
authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter
authc.loginUrl = /login.jsp

The FormAuthenticationFilter is easiest to use, but the
PasThruAuthenticationFilter is useful if you need to do additional
request processing beyond a standard login.  See the
FormAuthenticationFilter and the PassThruAuthenticationFilter JavaDoc
for more information.

Finally, when multiple realms are configured, Shiro's default
authentication strategy is to call each realm.  As long as at least
one of those realms authenticates successfully, the authentication
will be successful.  You can see this happen by using your debugger
and putting a breakpoint in the
org.apache.shiro.authc.pam.ModularRealmAuthenticator class's
'doAuthenticate' method.  You can change the strategy if you want to
as well (AllSuccessfulStrategy, FirstSuccessfulStrategy, etc - see the
ModularRealmAuthenticator JavaDoc for more).

HTH,

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com

On Thu, Feb 17, 2011 at 5:53 AM, Datta <ma...@yahoo.com> wrote:
>
> Hello Friends:
> I am trying to use Active Directory Realm in my web application
> I have to authenticate users against 2 Active Directory
> Need help with configuration?
>
> Questions:
> 1. First when the form is submitted, request does not reach LoginUser
> servlet? (Unable to figure out whats wrong with .ini)
> After disabling filter, request reaches Servlet, but realms are not
> available.:(
> 2. How do I know which realm is used by LoginUser servlet?
> 3. Where do I specifiy so that these realms are available to
> SecurityManager/DefaultWebSecurityManager?
> 4. I tried the example here
> http://www.ibm.com/developerworks/web/library/wa-apacheshiro/
> It works well but with only 1 realm
>
>
> Below is my shiro.ini, login.jsp, web.xml, login servlets doPost Method
> [main]
> sirRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
> sirRealm.systemUsername = xxxx
> sirRealm.systemPassword = xxx
> sirRealm.searchBase = OU=IT,OU=MA-Users,DC=cinfotec,DC=corp
> sirRealm.url = ldap://ad0.cinfotec.corp:389/
>
> xmrRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
> xmrRealm.systemUsername = xxxx
> xmrRealm.systemPassword = xxx
> xmrRealm.searchBase = OU=BU,OU=MA-Users,DC=cinfotec,DC=corp
> xmrRealm.url = ldap://ad1.cinfotec.corp:389/
>
> authc.loginUrl = /login.jsp
> [urls]
> # make sure the end-user is authenticated.  If not, redirect to the
> 'authc.loginUrl' above,
> # and after successful authentication, redirect them back to the original
> account page they
> # were trying to view:
> /** = authc
> ---------------------------------------------------------------
> login.jsp
> <form name="loginform" method="post" action='LoginUser'>
>    <table align="left" border="0" cellspacing="0" cellpadding="3">
>        <tr>
>            <td>Username:</td>
>            <td><input type="text" name="username" maxlength="30"></td>
>        </tr>
>        <tr>
>            <td>Password:</td>
>            <td><input type="password" name="password" maxlength="30"></td>
>        </tr>
>        <tr>
>            <td colspan="2" align="left"><input type="checkbox"
> name="rememberMe">Remember Me</td>
>        </tr>
>        <tr>
>            <td colspan="2" align="right"><input type="submit" name="submit"
> value="Login"></td>
>        </tr>
>    </table>
> </form>
> ---------------------------------------------------------------
> web.xml
>    <filter>
>        <filter-name>ShiroFilter</filter-name>
>
> <filter-class>org.apache.shiro.web.servlet.IniShiroFilter</filter-class>
>    </filter>
>    <filter-mapping>
>        <filter-name>ShiroFilter</filter-name>
>        <url-pattern>/*</url-pattern>
>    </filter-mapping>
>
>    <servlet>
>        <servlet-name>LoginUser</servlet-name>
>        <display-name>LoginUser</display-name>
>        <description>Servlet to autenticate User agains AD</description>
>        <servlet-class>com.siriusxm.security.Login</servlet-class>
>    </servlet>
>    <servlet-mapping>
>        <servlet-name>LoginUser</servlet-name>
>        <url-pattern>/LoginUser</url-pattern>
>    </servlet-mapping>
>
> ---------------------------------------------------------------
> LoginUser Servlet doPost
>
>    public void doPost(HttpServletRequest request, HttpServletResponse
> response) throws ServletException, IOException {
>        String url = "/login.jsp"; // Get the login page url fromm
> properties file
>        String username = request.getParameter("username");
>        String password = request.getParameter("password");
>        UsernamePasswordToken token =
>                new UsernamePasswordToken(username, password);
>
>        try {
>        Subject subject = SecurityUtils.getSubject();
>        subject.login(token);
>        //token.clear();
>        url = "/secure/index.jsp";
>
>        } catch (AuthenticationException e) {
>            logger.error("Error:" + e.getMessage());
>            e.printStackTrace();
>        }
>        RequestDispatcher dispatcher =
>             getServletContext().getRequestDispatcher(url);
>
>        dispatcher.forward(request, response);
>
>        }
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Help-with-configuring-mulitple-ActiveDirectory-in-web-app-tp6035984p6035984.html
> Sent from the Shiro User mailing list archive at Nabble.com.