• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4492
  • Last Modified:

How to retrieve User Principals using JAAS

I'm using JAAS for the very first time and spent a good half day trying to find a decent tutorial but can't.  I can get the Authentication process working fine.  I'm using JBOSS 4, and am using the JBOSS "DatabaseServerLoginModule" which will create a user principal and a role principal for me.

<application-policy name = "SSLogin">
       <authentication>
          <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
             flag = "required">
             <module-option name = "unauthenticatedIdentity">guest</module-option>
             <module-option name = "dsJndiName">java:/jdbc/PostgresSS</module-option>
             <module-option name = "principalsQuery">SELECT PASSWORD FROM SS_USER WHERE SS_USER_NAME=? AND ACTIVE_IND='true' AND DELETED_IND='false'</module-option>
             <module-option name = "rolesQuery">SELECT ROLE_ID, 'Role' FROM SS_USER WHERE SS_USER_NAME=?</module-option>
             
          </login-module>
       </authentication>
    </application-policy>

I have created a custom CallBackHandler called PassiveCallbackHandler a side from that I created no other files, no policy files or user files.  I'm strickly using the following code and it authenticates me fine.

ActionForward forward = null;
        LoginForm loginForm = (LoginForm)form;
       
        String username = loginForm.getUsername();
        String password = loginForm.getPassword();
       
        PassiveCallbackHandler pcbh = new PassiveCallbackHandler(username, password);
        LoginContext lc = new LoginContext("SSLogin",pcbh);
       
        try
        {
            lc.login();
            forward = mapping.findForward("success");
           
           
        }
        catch (LoginException e)
        {
            forward = mapping.findForward("failure");
        }
       
        return forward;
}

My question is after I've done this how do I access the principal throughout the application.  Do I have to manually store the subject in the session?  When I use HttpServletRequest.getUserPrincipal() I get null.  When I use EJBContext.getPrincipal() i get anonymous.

I want to accomplish two goals.  
1> I want to use Auditing in my CMP's and don't want to pass in a modified String, I'd like to use the getPrincipal().

2> I want to restrict certain pages of the site for particular roles.  I'm using struts.  I don't want a non manager typing in the url of a manager site.  I have tried to find good explanations on the net but they are all either command line or very very simple and don't give complete examples.

Thank-you
0
phoenixsilver
Asked:
phoenixsilver
  • 32
  • 23
1 Solution
 
aozarovCommented:
For standard jsp/servlets (that do not go thru struts servlet) you need to define a security-domin in jboss-web.xml
and in web.xml define the pages that requires authentication and the allowed access. (see http://www.javaworld.com/javaworld/jw-08-2001/jw-0831-jaas_p.html )

In struts the concept is similar (after all struts itself starts as a servlet),
In our project all the users had access to all the pages (they just had different content), so we just defined the /*.do to be restricted
in the web.xml (hence no change from standard j2ee web authentication)

but if you want to restrict access to some struts pages
(which we  didn't do)  

then you can have a look at:
Complete configuration of JAAS on JBOSS and STRUTS: http://www.javaworld.com/javaforums/showflat.php?Cat=2&Board=JavaSecurity&Number=2500&page=0&view=collapsed&sb=5&o=&fpart=1
0
 
phoenixsilverAuthor Commented:
Ok, well I've gone through the link and other links that were available through the postings and am still having some issues.

This is the modification I've done to my login-config.xml

<application-policy name = "SSLogin">
       <authentication>
              <login-module code = "org.jboss.security.ClientLoginModule" flag = "required"></login-module>
          <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
             flag = "required">
             <module-option name = "unauthenticatedIdentity">guest</module-option>
             <module-option name = "dsJndiName">java:/jdbc/PostgresSS</module-option>
             <module-option name = "principalsQuery">SELECT PASSWORD FROM SS_USER WHERE SS_USER_NAME=? AND ACTIVE_IND='true' AND DELETED_IND='false'</module-option>
             <module-option name = "rolesQuery">SELECT ROLE_ID, 'Role' FROM SS_USER WHERE SS_USER_NAME=?</module-option>
             
          </login-module>
       </authentication>
    </application-policy>

Here is my auth.conf located in <JBOSS_HOME>/server/default/conf and in <JBOSS_HOME>/client

srp-client {
   // Example client auth.conf for using the SRPLoginModule
   org.jboss.security.srp.jaas.SRPLoginModule required
   password-stacking="useFirstPass"
   principalClassName="org.jboss.security.SimplePrincipal"
   srpServerJndiName="SRPServerInterface"
   debug=true
      ;

   // jBoss LoginModule
   org.jboss.security.ClientLoginModule  required
   password-stacking="useFirstPass"
   ;

   // Put your login modules that need jBoss here
};

other {
   // jBoss LoginModule
   org.jboss.security.ClientLoginModule  required
   ;

   // Put your login modules that need jBoss here
};

client-login
{
      org.jboss.security.ClientLoginModule required;
};

SSLogin
{
      org.jboss.security.ClientLoginModule required;
      org.jboss.security.auth.spi.DatabaseServerLoginModule required
      dsJndiName="java:/jdbc/PostgresSS"
      principalsQuery="SELECT PASSWORD FROM SS_USER WHERE SS_USER_NAME=? AND ACTIVE_IND='true' AND DELETED_IND='false'";
      rolesQuery="SELECT ROLE_ID, 'Role' FROM SS_USER WHERE SS_USER_NAME=?"
      ;
};

Here is my web.xml file complete.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app >
   <distributable/>

   <servlet>
      <servlet-name>ActionServlet</servlet-name>
      <display-name>Struts Controller</display-name>
      <description></description>
     <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

      <init-param>
         <param-name>application</param-name>
         <param-value>ApplicationResources</param-value>
      </init-param>
      <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml      </param-value>
      </init-param>
        <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>ActionServlet</servlet-name>
      <url-pattern>*.do</url-pattern>
   </servlet-mapping>

   <taglib>
        <taglib-uri>/WEB-INF/struts-tiles-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-tiles-el.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/struts-html-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-html-el.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/c.tld</taglib-uri>
        <taglib-location>/WEB-INF/c.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/struts-bean-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean-el.tld</taglib-location>
      </taglib>
      
      <security-constraint>
            <web-resource-collection>
                  <web-resource-name>action</web-resource-name>
                  <url-pattern>*.do</url-pattern>
                  <http-method>HEAD</http-method>
                  <http-method>GET</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
            </web-resource-collection>
            
            <auth-constraint>
                  <description>Manager</description>
                  <role-name>1</role-name>
            </auth-constraint>
            <user-data-constraint>
                  <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
      </security-constraint>
      <login-config>
            <auth-method>FORM</auth-method>
            <form-login-config>
                  <form-login-page>/web/loginuser.do</form-login-page>
                  <form-error-page>/web/index.jsp</form-error-page>
            </form-login-config>
      </login-config>
      <security-role>
            <description>Manager</description>
            <role-name>1</role-name>
      </security-role>
</web-app>

I have this line in my jboss-web.xml file

<security-domain>java:/jaas/SSLogin</security-domain>

Now in my LoginAction class where I invoke the LoginContext.login() method it logins just fine.  But when I use request.getUserPrincipal() I get a null value.  Also I can login and if forwards me to the correct page but all other links that I use all forward me to the <form-login-page>/web/loginuser.do

I really have no clue on what's going on here.  Any help would be greatly appreciated.


0
 
phoenixsilverAuthor Commented:
I tried putting in a specific path to the web-resource-collection such as

web-resource-collection>
               <web-resource-name>action</web-resource-name>
               <url-pattern>/web/card/cardmanagement/*.do</url-pattern>
               <http-method>HEAD</http-method>
               <http-method>GET</http-method>
               <http-method>POST</http-method>
               <http-method>PUT</http-method>
               <http-method>DELETE</http-method>
          </web-resource-collection>

and it blows an exception saying org.jboss.deployment.DeploymentException: URL file:/D:/Projects/UFA/Pace_Phase_II/Development/eclipse/workspace/Self-Service/war/http.war/ deployment failed
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
aozarovCommented:
>> <security-domain>java:/jaas/SSLogin</security-domain>
Make sure that jboss-web.xml can be found in the war in the same place as web.xml.

1. on the serverside there is no need for auth.conf once you defined it in login-config.xml
2. We can do it step by step by first enable standard J2EE security (regardless struts) and then try to incorporate struts needs.
For that you can try the following:
a. comment out <login-module code = "org.jboss.security.ClientLoginModule" flag = "required"></login-module> in <application-policy name = "SSLogin">
b. comment out LoginContext.login() logic in your LoginAction class.
c. there is not much need for   <http-method>HEAD</http-method> ... if it applies to all HTTP request types.

Onced you did that and send an http request to any of your actions you are suppose to get an authentication dialog box.
Do you see it?
0
 
phoenixsilverAuthor Commented:
I don't know your name, but mine is Tushar and you've been an amazing help so far.  If you're every in Calgary, Canada let me know.

jboss-web.xml file is in the same place as the web.xml.

I've done everything and its not working.  Should I comment out the whole web.xml security-contraint...section with the http-method tags.  I only removed the head one.  I'm going to try and remove all of the method tags.  What I get is my html page with the login section comes up and behaves the same as before.  I didn't get a dialog box.  Should I remove all of the auth.conf files?



0
 
aozarovCommented:
>> I don't know your name, but mine is Tushar and you've been an amazing help so far.  If you're every in Calgary, Canada let me know.
My name is Arie. :-)

>> I didn't get a dialog box.  
Actually reading your previous message ".. links that I use all forward me to the <form-login-page>/web/loginuser.do"
This Suggests that the container do recognize that this resource is secured and provides the means to authenticate (though you don't use standard browser authentication dialog but rather a form based).
In your loginuser.do do you generate a standard FORM for authentication?

Something similar to that:
<form method="POST" action="j_security_check">
   <input type="text" name="j_username">
   <input type="text" name="j_password">
   <input type="submit" value="Log in">
</form>


>> Should I remove all of the auth.conf files?
Those should not be a problem though there are not used by the container when setting the login-config.xml file

There is an up-to-date version of http://www.javaworld.com/javaworld/jw-08-2001/jw-0831-jaas_p.html article which is maintained by JBoss and can be downloaded from http://sourceforge.net/docman/display_doc.php?docid=18240&group_id=22866
The link can also be accessed thru http://www.jboss.org/wiki/Wiki.jsp?page=JBossSX

Did you apply the changes in sections ‘a’ and ‘b’ mentioned above?
If after applying ‘a’ and ‘b’ and fixing (if needed) loginuser.do you don't see any change (you don't get the output of loginuser.do or you keep getting it for every page) then I advice you to install the JBoss article provided example see if that works for you and then compare the differences (and let me know about your findings ;-).
0
 
phoenixsilverAuthor Commented:
On my form this is what I essentially have.

<form name="LoginForm" method="post" action="<%=request.getContextPath()%>/web/loginuser.do">
<div class="tanbox" style="width: 300px">
<h3 class="centered">Log In</h3>
<table border="0" summary="Login table">
<tr>
    <th>Username</th>
    <td><input type="text" name="username" value=""></td>
  </tr>
  <tr>
    <th>Password</th>
    <td><input type="password" name="password" value=""></td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><input class="buttonstyle" type="submit" value="Submit"><p class="smalltext"><a href="#">Forgot Password?</a></ptd>
  </tr>
</table>
</form>

I didn't remove the auth.conf files.  I did make the changes a) and b) I commented out all of the code that uses JAAS Login stuff, plus I commented out the ClientLoginModule under SSLogin.  So I think you're right its still using FORM based authentication but I've got something screwed up.  I'm downloading the updated example and am going to run through it right now.

I will let you know how it goes.

0
 
aozarovCommented:
When applying form based authentication you need to have the form action to be equal to "j_security_check"
and username / password names should be j_username/ j_password (those are not arbitrary names but part of the protocol)
0
 
phoenixsilverAuthor Commented:
So is it j_security_check.do or without the do?  And same with the actionform should the form var be

private String j_username;
private String j_password;

then getters/setters?

This may work out better as that example is not exactly going well.  I have version 4 and I'm trying to mod it form a 3.2 example plus it doesn't have form authentication.  So I think I'm going to bail on it.  Maybe we found the problem.
0
 
phoenixsilverAuthor Commented:
So my Login.jsp page will look like this

<form method="post" action="j_security_check">
<div class="tanbox" style="width: 300px">
<h3 class="centered">Log In</h3>
<table border="0" summary="Login table">
<tr>
    <th>Username</th>
    <td><input type="text" name="j_username" value=""></td>
  </tr>
  <tr>
    <th>Password</th>
    <td><input type="password" name="j_password" value=""></td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><input class="buttonstyle" type="submit" value="Submit"><p class="smalltext"><a href="#">Forgot Password?</a></ptd>
  </tr>
</table>
</form>

My LoginAction class is going to look like this

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        ActionForward forward = null;
       
        String username = request.getParameter("j_username");
        String password = request.getParameter("j_password");
        SimplePrincipal user = new SimplePrincipal(username);
        PassiveCallbackHandler pcbh = new PassiveCallbackHandler(username, password);
        LoginContext lc = new LoginContext("SSLogin",pcbh);
        Subject subject = null;
       
        try
       {
            lc.login();
            subject = lc.getSubject();
            Set principals = subject.getPrincipals();
            forward = mapping.findForward("success");
        }
        catch (Exception e) //Add LoginException
        {
            forward = mapping.findForward("failure");
        }
       
       
        return forward;
}

Does this seem correct so far?  I have not changed anything back and still have all your recommended changes.

 
0
 
aozarovCommented:
The important part is for the HTML form (generated by loginuser.do) to have those names (as in the example above) [don't confuse it with the Struts ActionForm].
Once the HTML FORM is being submitted the results will be used by the container and not by any of your actions.
If you want to make it simpler (at first) then remove:
<login-config>
          <auth-method>FORM</auth-method>
          <form-login-config>
               <form-login-page>/web/loginuser.do</form-login-page>
               <form-error-page>/web/index.jsp</form-error-page>
          </form-login-config>
     </login-config>

Which will then use the browser dialog box to authenticate the users instead of the form generated by loginuser.do
0
 
phoenixsilverAuthor Commented:
All right so let me get this straight

It should look like this

<form name="j_security_check" method="post" action="/web/loginuser.do">

And I should remove the login-config tags to see the diaglog box?

0
 
phoenixsilverAuthor Commented:
I removed the login-config tags and what's in between ONLY and left all of the other security tags and the same url pattern and I didn't receive that dialog box.  Is my url-pattern correct?
0
 
phoenixsilverAuthor Commented:
This is what I got when I changed the url-pattern to /* so I know something is working, just don't know what


ERROR 403
Status report

message Configuration error: Cannot perform access control without an authenticated principal

description Access to the specified resource (Configuration error: Cannot perform access control without an authenticated principal) has been forbidden.

0
 
aozarovCommented:
<form name="j_security_check" method="post" action="/web/loginuser.do">
should be
<form method="POST" action="j_security_check">

see full example:
<form method="POST" action="j_security_check">
   <input type="text" name="j_username">
   <input type="text" name="j_password">
   <input type="submit" value="Log in">
</form>


The redirection to loginuser.do (that should generate this form) is done automatically by the container the first time you try to access a secured resource.
0
 
aozarovCommented:
So, when you removed login-config and change  url-pattern to /* did you get the browser authentication dialog box?
0
 
phoenixsilverAuthor Commented:
No I did not.  I've tried all your suggestions on that and some other random combinations and haven't received a diaglog box.
0
 
phoenixsilverAuthor Commented:
I'm sorry I'm a bit confused.

I name the form that way and then after I type my username/password into the login box it will redirect the login to my struts action class which will validate the user and continue on?  

Basically on our welcome page we have the login box.  That form i'm going to name j_security... and in the form-login should I put in my action class?
0
 
phoenixsilverAuthor Commented:
I hope I'm not annoying you too much, but I extremely, extremely am grateful for you help as this is a black box to me and I haven't been able to find any simple example of this.

What I've done now is put in a url pattern : /web/card/*

My login form is just like you said.

I now understand what you meant by the login but how do I get that form to submit to my action class, after the container is done with it where does it send it after its submitted?
0
 
aozarovCommented:
>> I'm sorry I'm a bit confused.
I think you look at it from the wrong angle.
The way it should work is like this:
1. User tries to access any page that will match the pattern for a security-constraint.
2. Once this happens the container will call directly to the page defined in <form-login-page> (in your case /web/loginuser.do)
3. The page generated by loginuser.do should contain an HTML form that follows the structure and action value and username/password names as I mentioned above.
4. Once the user submits this form the container will handle it (it knows it belongs to it by matching action value to "j_security_check"
5. At this stage the container will consult the Login module associated with java:/jaas/SSLogin security domain and verify/authenticate the user.
6. If authentication was successful the container will direct the user to its original request page (from section 1). At this point calling getUserPrincipal should have the right value.
7. If authentication failed the container will direct the user to this page "<form-error-page>/web/index.jsp</form-error-page>"
8. Once the user was authenticated the container will not ask for further authentication for that session.

* Note, if you omit the login-config tag then the flow is similar but instead of sending the user the html form generated from /web/loginuser.do it will send to the browser an error code 401 which will trigger the browser to popup an authentication dialog box.

For standard J2EE authentication there is no need to authenticate manfully (as you tried to do in the LoginAction).
 
Is that more clear?
0
 
phoenixsilverAuthor Commented:
Yes that's more clear.  I'm just trying it now.  But what about if you display a index page with the form on it.  How can you specify once the person logins in it gets redirected to a specific welcome page you want the user to be redirected to on the initial login?  I totally understand the part when you try and access a section that you are not allowed to that the container can save the requested URL.  The reason I want this is that based on a role we are redirecting the user to a specific welcome page.  Also we aren't displaying menu items are the role is NOT allowed to go to, its for if they type the url manually that we want the restriction so if they do that, is there a way I can either log them out or display a page that says they are not authorized?
0
 
aozarovCommented:
Ok, so now you are getting to the programatic part.
Once the user was already authenticated by the container and its session is associated with a UserPrincipal (which can be accessed from the servlet) and roles then you
can use the servlet isUserInRole to apply further checks and based on that show/hide menus and/ or redirect the user to other pages (via: ServletContext.getRequestDispatcher(..).forward or HttpServletResponse.sendRedirect(...) )
0
 
phoenixsilverAuthor Commented:
Great now where would I do this?  

With my current scenario, I want to place a login form on the welcome page.  I have a submit that submits to the j_security_check and then where do I get to start applying the programatic portion.  Once I click submit, it submits to this form and then when can I get control of it?  Once its authenticated I want control of it so I can put session info into this user's session and then redirect based on the role.  Currently I don't have that implementation.  Does this make sense?  I'd like to do it in an ActionClass.

Also does the role name <role-name>1</role-name> 1 correspond to the value that's in the database using the rolesQuery?
0
 
aozarovCommented:
>> Also does the role name <role-name>1</role-name> 1 correspond to the value that's in the database using the rolesQuery?
Yes, 1 should match the value returned from ROLE_ID using the rolesQuery (the value doesn't have to be numeric).

There are several ways to solve your needs based on this scenario.
One is to have a welcome page be the page that you want the client to get onced it got authenticated.
If that page URL (the welcome page) is going to match the pattern of the security then before getting that page the user will need to go thru the login process.
Another option is to have that non secure welcome page to redirect automatically to the needed page (which needs to be secure and then will go thru the authentication process as described above).
0
 
phoenixsilverAuthor Commented:
Ok, i get that much, but I'm wondering where do I code the redirection after login.  Sorry if I am not getting this, I work much better with visual code.  Do I code it in the filter, action class.  Is there a section in the web.xml file that I can say after authentication forward/redirect to this /web/SomeAction.do where I can then base my logic on and also have the Principal's set.

What I orginally did was have my own LoginContext and manually invoke the login method as you know and although it worked fine, I didn't have the principals set.  Even if I do option two that you have there, I could do what I originally did and use the LoginContext to authenticate, set my session variables and redirect them to the page that I desire but I don't get the Principals set.  For my app I would like to use the JAAS login so that I can also grab the principal in the EJB's for audit purposes without passing the username down.  The by product of this is I can put in security for paths in the web.xml file without writing my own logic.  I won't be displaying any links to restricted areas on the site, each role has there own menu.  

What I'm missing here is where can I perform the redirection once they login.  There isn't a place in the web.xml file for authentication success is there?  If so then I can send it to a Action class and all my problems are solved....I think:)
0
 
aozarovCommented:
>> although it worked fine, I didn't have the principals set.
Right, because this does not involve the web container in the authentication process.

>> For my app I would like to use the JAAS login so that I can also grab the principal in the EJB's for audit
The process we described above is applying Jaas login (though thru the container and not manually using LoginContext)

>> What I'm missing here is where can I perform the redirection once they login.
The process goes differently. You are thinking of going to a specific page then sending a login request and then authenticating and redirecting accordingly.
Though that process makes sense this is not how it is done via J2EE security (and normally is done when not using the J2EE authentication model). In the J2EE authentication world it is only when you access a page which has security constraints is when the authentication logic kicks in and associates the request with the user and its security credentials.
As I mentioned above you can still achieve the same results by defining your welcome page to be secure. This welcome page should not be login page but rather the page you want to get after you applied the login process. The container will intercept the call to that page and will require the client to authenticate before redirecting it to that page.
When the authentication process is done and the user request is forwarded to the welcome page that welcome page logic can use and check the user credentials/roles by calling the standard Servlet API calls (getUserPrincipal and isUserInRole). Also, if that Servlet is using EJB those credentials will be propagated to the EJB transparently.
Don’t fear to ask more questions if you need more clarification.
I also advice you to setup the example from the JBoss provided link and play with it.
0
 
phoenixsilverAuthor Commented:
Now I get it!  Its unfortunate though that they didn't incorporate what I'm looking for as it seems logical that one would allow the container to maintain credentials and have custom code piggy back off of that.  

So yeah I can protect the welcome page and have then redirect to a login, but I lose the ability to place custom session information into the session and redirect based on specific roles.

This leaves me with a bit of a delema now on how to implement my site.

I tried that example but its for JBoss 3.2 which really doesn't matter normally but the ant script had a bunch of specific things on 3.2 and since I was at work I just didn't have the time to go through it.  But I am going to think about this over night.  I wish J2EE would have figured out that people could have used more functionality.
0
 
aozarovCommented:
>>  but I lose the ability to place custom session information into the session and redirect based on specific roles.
Your "secured" welcome page which will have the user roles and credentials can still forward [ServletContext.getRequestDispatcher(..)] to different pages based on the user roles...

I agree that J2EE security is pretty poor and has lots of room for improvements :-(
0
 
phoenixsilverAuthor Commented:
Where would I put that snippet of code?

Also would I have more control if I created my own LoginModule?
0
 
aozarovCommented:
>>  Where would I put that snippet of code?
The welcome page struts Action can get the user roles and based on that to forward to different pages.
You can use ServletContext.getRequestDispatcher(..) if your welcome page is plain Servlet or JSP and not a struts action (the idea is the same).

The LoginModule can be used (as I think shown in the example) when you want to authenticate via java client that access the EJB directly.
It is not normally used in the Web tier. The problem with authentication via LoginModule in the struts actions/servlets layer is that it happens after the web container created/filled the HttpServletRequest and therefore that request will not contain the user information (when calling to getUserPrincipal or isUserInRole). Even though the information will not be in the HttpServletRequest it is going to be associated with the Thread
and any request to the EJB layer should propagate it. I don't recommend you to go this route but rather try to make the J2EE standard authentication work for you.
0
 
phoenixsilverAuthor Commented:
Ok, so let me see if I've got this right now.

I create a welcome page that is under a security page so that the JAAS login gets set.  My welcome page is /web/index.jsp and it contains the form with j_security_check.  Then I create a custom servlet that will get redirected to once this form has been submitted and authenticated.

Now once I press submit how do I get it to go to a servlet like you suggested.

Again sorry for the redundancy, as I don't see the flow as of right now.  I appreciate your patience Arie.
0
 
aozarovCommented:
>> Ok, so let me see if I've got this right now.
Almost :-)
As you said you create either a JSP page (e.g. /web/index.jsp) or a custom Servlet that will be under a secure URL path and defined as a welcome page.
That JSP/Servlet will have logic to redirect the user to its matching page (admin, user, ...) based on checking the user credentials. This page should not contain the j_security_check form.
In addition you create a login jsp page that will have the j_security_check HTML form and you define that page as form-login-page.
Once the user enters your site he/she will be directed to the welcome page but because this welcome page is secured the user will be first prompted by the web container with your login page and only after a successful authentication process the container will forward (automatically) to the original requested page (in your case the welcome page, where you have the logic of further redirection based on the user credentials).
0
 
phoenixsilverAuthor Commented:
so I think I might have gotten it.

I'm going to put a /* restriction on everything.  My welcome page is going to be /loginuser.do and my login-form in the web.xml file is going to be index.jsp.  This will force the j_security_check once they login they will be sent to /loginuser.do where I can add my session variables to the user and proceed to redirect to the appropirate page.

Do I go it?
0
 
aozarovCommented:
Seems so :-)
Just ot make sure: in that case your index.jsp is going to have the form with j_security_check
0
 
phoenixsilverAuthor Commented:
I tried this and so far it looks like its working.

I have a swf file in an include directory and its saying I don't have permission to it.

My dir struct is

/include
           - interstate_cond_reg.swf
          - site.css
/image
/web
          - all my jsp's
/WEB-INF
          - all my files needed here.


Anything special I need to do to include these under the permissions.  I type in http://localhost:8080/http/web/login.do and get redirected to my JAAS login page.

How do I specify paths for anyone and have no security on it?  Like all my css and includes because that too isn't coming up on the opening page, I'm assuming its because its not in the security path.
0
 
phoenixsilverAuthor Commented:
I'm trying to put files that are required by everyone under the "*" role
0
 
phoenixsilverAuthor Commented:
So after I tried that I don't get a 403 permission error anymore but it now just keeps hanging and oh yeah on my j_security page my css doesn't show up.
Plus after I've logged in its supposed to forward me to /login.do but in the url path in the browser I get this http://localhost:8080/http/include/interstate_cond_reg.swf

This is what i have in my web.xml file now.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app >
   <distributable/>

   <servlet>
      <servlet-name>ActionServlet</servlet-name>
      <display-name>Struts Controller</display-name>
      <description></description>
     <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

      <init-param>
         <param-name>application</param-name>
         <param-value>ApplicationResources</param-value>
      </init-param>
      <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml      </param-value>
      </init-param>
        <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
      <servlet-name>ActionServlet</servlet-name>
      <url-pattern>*.do</url-pattern>
   </servlet-mapping>

   <taglib>
        <taglib-uri>/WEB-INF/struts-tiles-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-tiles-el.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/struts-html-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-html-el.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/c.tld</taglib-uri>
        <taglib-location>/WEB-INF/c.tld</taglib-location>
      </taglib>
      <taglib>
        <taglib-uri>/WEB-INF/struts-bean-el.tld</taglib-uri>
        <taglib-location>/WEB-INF/struts-bean-el.tld</taglib-location>
      </taglib>
      
      <security-constraint>
            <web-resource-collection>
                  <web-resource-name>action</web-resource-name>
                  <url-pattern>/web/*</url-pattern>
                  <http-method>GET</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
                  <http-method>HEAD</http-method>
            </web-resource-collection>
            <auth-constraint>
                  <description>Manager</description>
                  <role-name>1</role-name>
            </auth-constraint>
            <user-data-constraint>
                  <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
      </security-constraint>
      
      <security-constraint>
            <web-resource-collection>
                  <web-resource-name>include</web-resource-name>
                  <url-pattern>/include/*</url-pattern>
                  <http-method>GET</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
                  <http-method>HEAD</http-method>
            </web-resource-collection>
            <auth-constraint>
                  <role-name>*</role-name>
            </auth-constraint>      
            <user-data-constraint>
                  <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
      </security-constraint>
      
      <security-constraint>
            <web-resource-collection>
                  <web-resource-name>image</web-resource-name>
                  <url-pattern>/image/*</url-pattern>
                  <http-method>GET</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
                  <http-method>HEAD</http-method>
            </web-resource-collection>
            <auth-constraint>
                  <role-name>*</role-name>
            </auth-constraint>      
            <user-data-constraint>
                  <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
      </security-constraint>
      
      <security-constraint>
            <web-resource-collection>
                  <web-resource-name>layouts</web-resource-name>
                  <url-pattern>/layouts/*</url-pattern>
                  <http-method>GET</http-method>
                  <http-method>POST</http-method>
                  <http-method>PUT</http-method>
                  <http-method>DELETE</http-method>
                  <http-method>HEAD</http-method>
            </web-resource-collection>
            <auth-constraint>
                  <role-name>*</role-name>
            </auth-constraint>      
            <user-data-constraint>
                  <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
      </security-constraint>
      
      <login-config>
            <auth-method>FORM</auth-method>
            <form-login-config>
                  <form-login-page>/web/index.jsp</form-login-page>
                  <form-error-page>/web/error.jsp</form-error-page>
            </form-login-config>
      </login-config>
      <security-role>
            <description>Manager</description>
            <role-name>1</role-name>
      </security-role>
</web-app>
0
 
aozarovCommented:
1. I don't think you need to define security-constraints for pages that don't require such security (such as images, css, include, ...)
Maybe there is be a problem with the login page (index.jsp?) but lets leave that for later. The rest of the pages should be
able to acces to the resources with having security constraints on them.
If you do decide to have constraint on them then I don't think you can use "*" you shoud use some value that will return to all the users
when the query SELECT ROLE_ID, 'Role' FROM SS_USER WHERE SS_USER_NAME=? is applied (that query can return more then one role per user).

Do you mind to take those constraints out (just leave the one for /web/*) then go to http://localhost:8080/http/web/login.do (assuming http is your web application context name)
Tell me if this is what you see.
1. you get the index.jsp (login form) is it still without css? If so show your your css include path
2. Are you being directed to /web/login.do after a scessful login? where is that action take you
3. Can you access after pages in the application (after sucessful authentication) using the same browser without the need to authenticate again?
4. can you try to grab http://localhost:8080/http/image/ <one of your images> without the need of authentication?
0
 
phoenixsilverAuthor Commented:
Funny, now I did what you said, removed all of the * security things, only left /web/* and the csss and images comes up just fine.

The problem is now that when I login I'm getting a

Access to the specified resource (Access to the requested resource has been denied) has been forbidden.

And the URL in the browser is fine.  I think my roles query maybe wrong

Here is the query
SELECT ROLE_ID, 'Role' FROM SS_USER WHERE SS_USER_NAME='tushar'

Here is the result

role_id    |   ?column?
--------------------------
   1         |     Role

Now I'm not sure if that is properly mapped to what I put in the xml file.  I did put the number 1
0
 
aozarovCommented:
Yes, that looks ok.
Do you have the password set right?
Change the log level for jboss security to see what is going on in the authentication process.
0
 
phoenixsilverAuthor Commented:
Yep, password is right because when I type the wrong password I get taken to the login-error page in the web.xml.  I'll try the logging.
0
 
phoenixsilverAuthor Commented:
This is all the logging spewed out before it went to the error page.

13:19:21,644 DEBUG [JaasSecurityManagerService] Created securityMgr=org.jboss.security.plugins.JaasSecurityManager@129efd0
13:19:21,644 DEBUG [SSLogin] CachePolicy set to: org.jboss.util.TimedCachePolicy@3f6843
13:19:21,644 DEBUG [JaasSecurityManagerService] setCachePolicy, c=org.jboss.util.TimedCachePolicy@3f6843
13:19:21,644 DEBUG [JaasSecurityManagerService] Added SSLogin, org.jboss.security.plugins.SecurityDomainContext@d6466f to map

0
 
aozarovCommented:
change the conf/log4j.xml to have

<category name="org.jboss.security">
        <priority value="TRACE" class="org.jboss.logging.XLevel"/>
</category>

and make sure your appender does not filter out levels below debug
0
 
phoenixsilverAuthor Commented:
Ok, I got it to work, the problem I had was in my query I had "Role" instead of "Roles"

Now my next question.  How can I specify a page saying you're not authorized instead of using the jboss pages.  I know the error page is for if you can't login it will take you somewhere, but if an unauthorized page is accessed can you display a custom page?
0
 
aozarovCommented:
I don't think it is a JBoss issue but rather might be a web container (Tomcat or Jetty which one you use) configuration.
JBoss refuses the access and then the web container decides what to do with it and I think in your
case it doesn't generate html response but rather returns HTTP Error 403. I think the message you see comes
from your browser.
Try setting this element in your web.xml
// From the DTD
<!ELEMENT error-page ((error-code | exception-type), location)>
<error-page>
<error-code>
403
</error-code>
<location>
your_url_to_the_error_page
</location>
</error-page>
0
 
phoenixsilverAuthor Commented:
Have you seen this before?

HTTP Status 408 - The time allowed for the login process has been exceeded. If you wish to continue you must either click back twice and re-click the link you requested or close and re-open your browser
0
 
aozarovCommented:
No, when does it happen?
0
 
phoenixsilverAuthor Commented:
Well I have a index.jsp at my base that redirects to a /web/setupsession.do but since its in a secure area it gets redirected to the login page.  That's when I login and get that message.

You know the more I'm working with this the more I just think its not worth it.  Its very limited.
0
 
phoenixsilverAuthor Commented:
Thanks Arie for all your help.  I'm going to have to think about this for awhile as I think that it may not be the best solution we're looking for even though it does what I need.
0
 
aozarovCommented:
J2EE security is limited but if you don't need to apply an instance based authentication (authenticate user based on functionality and data) then it is normally sufficient.
If you change your mind and/or need more help I will be happy to assist via this thread.
0
 
phoenixsilverAuthor Commented:
I need to implement both.  Since I am working on a pretty simple site with only 2 roles I think a customer solution will work fine.  But I am going to work on this as I am probably going to larger project with an oil and gas company and stricter security constrainsts will be needed.
0
 
aozarovCommented:
If the provided J2EE security framework will not match your needs then try to look for some third party solutions:
http://www.google.com/search?sourceid=navclient&ie=UTF-8&rls=RNWE,RNWE:2004-36,RNWE:en&q=j2ee+security+framework
Don't rush to build one yourself at least not until you fully understand their needs and the complexity involved ;-)
0
 
phoenixsilverAuthor Commented:
How would you logout the session using JAAS?  It just clicked to me I don't know how to do that.
0
 
phoenixsilverAuthor Commented:
I should clarify that using the auto login that we have talked about here, how can I logout, or get a reference to the login context to log it out since I'm not using it to login?
0
 
aozarovCommented:
You logout automatically onced you leave the page that triggered the authentication process.
The are two issue thoug:
1. your browser now holds this credentials and will keep use them to authenticate itself
2. JBoss caches the credentials and will not call your login module again (for a certain time).
You can flush JBoss cache (which will trigger your login module again) see this for a howto: http://www.mail-archive.com/jboss-user@lists.sourceforge.net/msg44729.html
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 32
  • 23
Tackle projects and never again get stuck behind a technical roadblock.
Join Now