Hi!

I was asked by a response to my blog post 
(http://roneiv.wordpress.com/2008/02/19/perform-a-jaas-programmatic-login-in-jboss-try-to-solve-the-empty-remote-user-problem/)
  to comment and maybe help on this issue.

I'm no expert on these matters, but I've managed to use the WebAuthentication 
BOTH from servlet context and from a handler to login a user to the 
application. And the user is properly set also in web container, so both 
externalContext.getRemoteUser() AND 
externalContext.getUserPrincipal().toString() return the logged on username.

Zilbi, it is my understanding that you have managed to log on to your 
application whith basic form-logon, using j_security_check etc. That's nice, 
because we then know that your login-config and ds works. Still, I will provide 
an example of the login-config I use, just in case it matters ;) This one uses 
a database with a user table, but the groups are static:


  | <application-policy name = "myApplication">
  |       <authentication>
  |       <login-module code = 
"org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
  |             <module-option name = 
"dsJndiName">java:/myDatasource-ds</module-option>  
  |             <module-option name = "principalsQuery">Select password from 
user_table where user_name =? AND active = 'true'</module-option>
  |             <module-option name = "rolesQuery">Select 'user', 'Roles', 
'RoleGroups' from user_table where user_name =?</module-option>
  |             <module-option name ="hashAlgorithm">md5</module-option>
  |             <module-option name="hashEncoding">hex</module-option>
  |             <module-option name="debug">false</module-option>
  |      </login-module>
  |      <login-module code="org.jboss.security.ClientLoginModule" 
flag="required" />
  |      </authentication>
  |  </application-policy>
  | 

The first thing to try is that the WebAuthentication class works as it should.
Create a LoginHandler or something similar, with a method login() and two 
helper-methods getRemoteUser and getUserPrincipal. Something like this:


  | public class LoginHandler
  | {
  |  
  | public String login()
  | {
  |             WebAuthentication webAuthentication = new WebAuthentication();
  |             
  |             String hardcodedUserName = "[EMAIL PROTECTED]";
  |             String hardcodedPassword = "zilbi123";
  |             
  |             if (webAuthentication.login(hardcodedUserName, 
hardcodedPassword))
  |             {
  |                System.out.println("Logged in successfully");;
  |             
  |                     log.debug("userPrincipal: " + getUserPrincipal());
  |                     log.debug("remoteUser: " + getRemoteUser());
  |             }
  |             else
  |             {
  |                     log.debug("Login failed");
  |             }
  |     
  |             return "";
  | }
  | public String getUserPrincipal()
  | {
  |             FacesContext context = FacesContext.getCurrentInstance();
  |             ExternalContext externalContext = context.getExternalContext();
  |             return externalContext.getUserPrincipal() != null ? 
externalContext.getUserPrincipal().toString() : "null";
  | }
  | 
  | public String getRemoteUser() 
  | {
  |             FacesContext context = FacesContext.getCurrentInstance();
  |             ExternalContext externalContext = context.getExternalContext();
  |             String remoteUser = externalContext.getRemoteUser();
  |             return remoteUser;
  | }
  | 
  | }
  | 

We basically hardcode the username/password, and just test if we get login to 
work. You should of course change these values to something that matches your 
login domain. Then create a simple jsp, but don't put it inside your protected 
folder. I see from you web.xml that you protect everything under /protected/*. 
Create it one level up so that you can access it without being asked to log in.

In this jsp you will have a stupid commandButton, as well as two outputs that 
displays the remoteUser and userPrincipal:


  | <f:view >
  |     <t:document>
  |     <t:documentHead>
  |        <f:loadBundle basename="MessageResources" var="messages" />
  |     </t:documentHead>
  | 
  |     <f:verbatim>
  |             <body>
  |     </f:verbatim>
  |     <h:form>
  |             <h:panelGrid>
  |                     <h:commandButton value="Login" 
action="#{loginHandler.login}"></h:commandButton>
  |                     <h:outputText value="User Principal: 
#{loginHandler.userPrincipal}"></h:outputText>     
  |                     <h:outputText value="Remote User: 
#{loginHandler.remoteUser}"></h:outputText>   
  |             </h:panelGrid>
  |     </h:form>
  |     <f:verbatim>
  |             </body> 
  |     </f:verbatim>
  |     </t:document>
  | </f:view>
  | 

Now, launch your application by going to this page. You will see that 
userPrincipal shows "null" and remoteUser is empty. Press the Login button. 
When the page reloads it should display your username in both outputTexts. If 
you check your log or console it should say "Logged in successfully." The user 
is now properly set in the web container. Do you get this to work? Also, if you 
now try to change the url to go to one of your protected pages, you should not 
be redirected to any login.jsp, but the page should display properly - because 
you are already logged on.

Then, to do the logon from a servlet there's really not a big difference. I set 
up my web.xml to use a FORM-based logon, like this:


  | <login-config>
  |     <auth-method>FORM</auth-method>
  |     <form-login-config>
  |      <form-login-page>/login.faces</form-login-page>
  |      <form-error-page>/loginFailed.faces</form-error-page>
  |     </form-login-config>
  |    </login-config>
  | 

I also register my LoginServlet in web.xml like this:

  | <servlet>
  |     <servlet-name>LoginServlet</servlet-name>
  |     <servlet-class>com.test.servlet.LoginServlet</servlet-class>
  |   </servlet>
  |   
  |   <servlet-mapping>
  |     <servlet-name>LoginServlet</servlet-name>
  |     <url-pattern>/LoginServlet</url-pattern>
  |   </servlet-mapping>
  | 

My login.jsp is 99% the same as when using j_security_check, we just point the 
action to the LoginServlet instead:

  | <form method="POST" name="loginform" 
action="${pageContext.request.contextPath}/LoginServlet">
  |     <table style="vertical-align: middle;">
  |     <tr>
  |             <td>Username:</td><td><input type="text" 
name="j_username"/></td>
  |     </tr>
  |     <tr>
  |             <td>Password:</td><td><input type="password" 
name="j_password"/></td>
  |     </tr>
  |     <tr>
  |             <td><input type="submit" value="Login" /></td>
  |     </tr>
  |     </table>
  | </form>
  | 
  | 

My LoginServlet uses the parameters that was originally passed to the 
j_security_check. Also, if we successfully log on, we get the "Referer" from 
the request to redirect to the page that originally was the target for the 
user. I did not include the code that handles if the logon failed here:

  | public class LoginServlet extends HttpServlet
  | {
  |     @Override
  |     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  |                     throws ServletException, IOException
  |     {
  |             // TODO Auto-generated method stub
  |             doPost(req, resp);
  |             
  |     }
  |     
  |     @Override
  |     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  |                     throws ServletException, IOException
  |     {
  |             String user = req.getParameter("j_username");
  |             String pass = req.getParameter("j_password");
  |             WebAuthentication webAuthentication = new WebAuthentication();
  |             if(     webAuthentication.login(user, pass))
  |             {       
  |                     String redirectUrl = "";
  |                     String referer = req.getHeader("Referer");
  |                     resp.sendRedirect(redirectUrl);
  |                     return;
  |             }
  |             else
  |             {
  |                     System.out.println("Login attempt failed " + user);
  |                     ...
  |                     Handle incorrect logon, go back to login page etc
  |                     ...
  |             }
  |     }
  | }
  | 

So, to test this, start your application by pointing directly to some page that 
is protected. Your login.jsp should be presented, and when you press Login the 
servlet uses the credentials you passed in the forms, authenticates and 
redirect you to the page. For debug reasons you could add the same outputTexts 
here on this page (remoteUser and userPrincipal), and they SHOULD show the user 
you logged in with now. 

Hope that this might help you, but as I said, I'm no expert on this. And I 
don't know the effect of the two options you include in your login-config, if 
this could cause some bad behaviour or not:
anonymous wrote : 
  | <module-option name="restore-login-identity">true</module-option>
  |                             <module-option 
name="multi-threaded">true</module-option>

A good tip is to start with a minimal configuration till you get it working, 
and then slowly building it up to go where you want. :)

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4136856#4136856

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4136856
_______________________________________________
jboss-user mailing list
jboss-user@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to