0

i have a log in page, where a user enters the username and password :

<form method="post" action="j_security_check">
                    <p>You need to log in to access protected information.</p>
                    <table>
                        <tr>
                            <td>User name:</td>
                            <td><input type="text" name="j_username" /></td>
                        </tr>
                        <tr>
                            <td>Password:</td>
                            <td><input type="password" name="j_password" /></td>
                        </tr>
                    </table>
                    <p><input type="submit" value="Login" /></p>
                </form>

What i am now trying to do is use the username that have been submmitted, i want to populate an input text box with this username automatically, but do not know how to do this, any ideas ?

user1924104
  • 891
  • 2
  • 16
  • 38
  • Related: http://stackoverflow.com/questions/2206911/best-way-for-user-authentication-on-javaee-6-using-jsf-2-0/2207147#2207147 – BalusC Jan 21 '13 at 18:22
  • Thank you, i am confused by the example however, is there not an easier way to call the username in the bean ? so instead of `@Override public String getName() { return getId(); }` i could replace getName() with the username , and if so how – user1924104 Jan 21 '13 at 19:25
  • Alonso has already answered that username is available by `ExternalContext#getRemoteUser()`. – BalusC Jan 21 '13 at 20:07

2 Answers2

1

when using container managed authentication (as it seems is your case) the username gets stored in the container security context. The Servlet spec provides an API that allows access to the user principal (an instance of java.security.Principal) which holds the user name.

So, once the user is logged in you can access the user principal with HttpServletRequest.getUserPrincipal() or username HttpServletRequest.getRemoteUser() from java code. Or with FacesContext.getCurrentInstance().getExternalContext().getRemoteUser()

To use it on a JSP/JSF file you could access it using the expression language this way: #{request.remoteUser} as in:

<h:inputText id="username" value="#{request.remoteUser}" />

Addition:

Your user backing bean:

public class User implements Serializable {

   private String name;

   // other user attributes here

   public String getName() {
      return name;
   }

}

Add JSF Filter:

public class SetupUserFilter implements Filter {

   public void init(FilterConfig config) { }

   public void destroy() { }

   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
      HttpServletRequest request = (HttpServletRequest) req;
      HttpSession session = request.getSession(false);
      if (session != null) {
         User user = session.getAttribute("user");
         if (user == null && request.getUserPrincipal() != null) {
            // This means user has just logged in.            
            String username = request.getRemoteUser();
            User user = ... // load the User instance from the database using the username
            session.setAttribute("user", user);
         }
      }

      chain.doFilter(req, res);
   }

}

Configure your filter in your web.xml:

<filter>
  <filter-name>SetupUserFilter</filter-name>
  <filter-class>com.example.SetupUserFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>SetupUserFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Then rely always on the User bean:

<h:inputText id="username" value="#{user.name}" />

Disclaimer: This is just an example, a bit old as it uses filters and other approaches may be valid as well but this one works even in non-JSF environments. Feel free to use it but understand that this is not the only way to get what you are looking for.

Alonso Dominguez
  • 7,750
  • 1
  • 27
  • 37
  • ok thank you, where would i have to place this, as i just want the username ideally – user1924104 Jan 21 '13 at 16:35
  • The only issue is, i did have `value="#{user.id}"` as the input, that corrospended with a backing bean `@Override public String getName() { return getId(); }` but how would i use the `request.remoteUser` for this ? – user1924104 Jan 21 '13 at 17:11
  • I would say that, once authenticated you should create your backing bean and then just rely on it for the rest of the session. I would create the `User` bean performing a search against the database using the `HttpServletRequest.getRemoteUser()` as the userId and then storing the backing bean in the session. – Alonso Dominguez Jan 21 '13 at 17:30
  • do you by any chance have an example ? i am a lil confused, newbie here ! – user1924104 Jan 21 '13 at 17:32
  • @user1924104 added example, just keep in mind it's not the only way of doing that – Alonso Dominguez Jan 21 '13 at 17:56
  • Thank you, i am confused by the example however, is there not an easier way to call the username in the bean ? so instead of `@Override public String getName() { return getId(); }` i could replace getName() with the username ? and if so how – user1924104 Jan 21 '13 at 19:23
  • if you just want the username and nothing else (a `String` value) then forget the bean, the filter and everything, just either use the `HttpServletRequest.getRemoteUser()` or the `#{request.remoteUser}` expression depending if you are working with Java code or with a JSP/JSF. The approach with the backing bean is just intended in case you want to place an object in the session holding all the data of your user, which is a common approach by the way. Notice that my example is not _everything you need_, just a starting point, you need to _fill the gaps_... – Alonso Dominguez Jan 21 '13 at 20:01
1

First, you have to define a managed bean to store the user's data:

@Named
@SessionScoped
public class User implements Serializable {
   private String name;
   private String password;

   public String getName() {
      return name;
   }

   public String setName(String name) {
      this.name = name;
   }

   public String getPassword() {
      return password;
   }

   public String setPassword(String password) {
      this.password = password;
   }
}

Of course that you'll have to implement some kind of encryption for your password, but this is just to demonstratate how to create a simple bean.

Next, your form would use EL (expression language) to set the user input to the corresponding beans' fields:

<h:form>
   <h3>Please enter your name and password.</h3>
   <table>
      <tr>
      <td>Name:</td>
      <td><h:inputText value="#{user.name}"/></td>
      </tr>
      <tr>
      <td>Password:</td>
      <td><h:inputSecret value="#{user.password}"/></td>
       </tr>
   </table>
   <p><h:commandButton value="Login" action="hello"/></p>
</h:form>

Finally, you can display the input on the hello.xhtml page:

<h:head>
   <title>Welcome</title>
</h:head>
<h:body>
   <h3>Hello #{user.name}, your password is #{user.password}</h3>
</h:body>
Rafael Companhoni
  • 1,780
  • 1
  • 15
  • 31
  • Thank you very much, only issue, is i must keep the login page as it is, as it authenticates to a LDAP server, would i simply add the value = ... bit onto it ? – user1924104 Jan 21 '13 at 15:19