Hi!
I was asked by a response to my blog post
(
http://roneiv.wordpress.com/2008/02/19/perform-a-jaas-programmatic-login-...)
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 = "zilbi(a)jboss.com";
| 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#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...