0

I've a JSF-Hibernate web application. I need to authenticate users against a Windows AD and the web application should only allow logins from members of group X, otherwise it should redirect to an error page. How can I configure this?

Also, I would like to display the name of the logged-in user on all pages, not the name of the Windows user of the server machine. I have tried the System.property("user.name") for this, but this only returns the name of the Windows user of the server name.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Potinos
  • 371
  • 3
  • 5
  • 15

2 Answers2

4

You need to create a so-called "LDAP Realm" on the servletcontainer. How to do this depends on the servletcontainer used. As you didn't give any details about the servletcontainer used, it's hard to give a suitable answer, but in general just reading the servletcontainer's documentation about Realm configuration ought to be sufficient. In case of for example Tomcat, it's the Realm Configuration HOW-TO. For Tomcat, you would need a JNDIRealm. More detail can be found in the JSP wiki.

Then you need to configure your web application to require a login for the particular pages by declaring the appropriate <security-constraint> entry in web.xml. You can configure the login and error page in <login-config> entry in the very same web.xml.

<security-constraint>
    <web-resource-collection>
        <web-resource-name>secured</web-resource-name>
        <url-pattern>/secured/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>X</role-name> <!-- Should be your AD group name. -->
    </auth-constraint>
</security-constraint>

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.xhtml</form-login-page>
        <form-error-page>/error.xhtml</form-error-page>
    </form-login-config>
</login-config>

The login form should POST to j_security_check and use j_username and j_password as input field names.

<form action="j_security_check" method="post">
    <input type="text" name="j_username" />
    <input type="password" name="j_password" />
    <input type="submit" value="login" />
</form>

If you want more fine grained control over validation and thus want to use JSF <h:inputText required="true" /> and so on, then you could also submit to a backing bean action method which in turn invokes HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check

As to getting the name of the logged-in user, just use ExternalContext#getRemoteUser() in JSF context or HttpServletRequest#getRemoteUser() in servlet context. You can access it in JSF EL as well as follows:

<p>Welcome, #{request.remoteUser}</p>

The system property indeed returns the server's own user which makes absoutely no sense in this context.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • You answaer seems realy efficient, but like i see it needs time to be implemented, for me I dont have access to the AD server, so, if your have a methode like System.property("user.name") that gives the name of the current user of the client windows's user! – Potinos Jun 19 '12 at 16:28
  • I'm working with tomcat as server! I'm alose working with JSF so i dont know how to call #{request.remoteUser} in equivalent way with JSF? Thank you so much! – Potinos Jun 19 '12 at 16:31
  • That's not possible if the client isn't logged in to your webapp. If you're using Tomcat, then the given links should be perfectly suitable to you. Configuring the server is by the way the responsibility of the server admin. You seem to be "just" a web developer. Are you sure that you're supposed to be the one who should configure the servletcontainer side? Talk with your project lead and/or server admin if possible. The `#{request.remoteUser}` **is** the JSF way. I have even explicitly mentioned that *"You can access it in JSF EL as well as follows:"* Do you understand the answer in any way? – BalusC Jun 19 '12 at 16:31
0

I would like to suggest you look at the open source project of oVirt . We have there a webadmin, based on GWT, and a REST-API web application that performs authentication against LDAP servers, using Kerberos as Authentication protocol (it supports also SIMPLE authentication).

I will describe here in general what we do, but please - take a look at the code:

  • We use JAAS + Krb5LoginModule in order to perform login operation to Kerberos (you must either set Kerberos related information via System.setProperties, such as the KDC, or use a krb5.conf file)

  • After login successful, we run a PrivilegedAction (see JAAS API)

  • Our PrivilegedAction uses GSSAPI (this is for Kerberos, you can also use SIMPLE instead) and has proper credentials as a result of the successful login.

At this point, you are authenticated against Active-Directory which serves both as Ldap server and KDC

This solution is container-independent and can work even from a simple, standalone Java program (of course you need to define a proper JAAS conf file. If you're using JBoss AS 7.1.x, as we do, standalone.xml takes care of this issue

The code resides at ovirt-engine/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/adbroker, and you can fetch it from oVirt by git clone.

Shaun the Sheep
  • 22,353
  • 1
  • 72
  • 100
Yair Zaslavsky
  • 4,091
  • 4
  • 20
  • 27