0
votes

I'm trying to set up a web application based on glassfish 3.1 + JSF2. The authorization is performed using a CAS server installing the jasig cas client in the web app as suggested here:

Configuring the JA-SIG CAS Client for Java in the web.xml

and I'm able to catch the principal object inside an EJB when the user is authenticated. CAS principal attributes comes from LDAP on Active Directory. Now how can I add authorization? How can I enable the access of certain web pages only to specific groups of users defined in AD?

The purpose is just to let users access different web pages according to their LDAP roles. I've tried to follow Securing Web Applications from the Java EE tutorial and my web.xml is

<filter>
    <filter-name>CAS Authentication Filter</filter-name>
    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
    <init-param>
        <param-name>casServerLoginUrl</param-name>
        <param-value>https://casserver:8443/cas/login</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
</filter>
<filter>
    <filter-name>CAS Validation Filter</filter-name>
    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
    <init-param>
        <param-name>casServerUrlPrefix</param-name>
        <param-value>https://casserver:8443/cas</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
</filter>
<filter>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!-- 
<filter>
    <filter-name>CAS Assertion Thread Local Filter</filter-name>
    <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
 -->
<filter-mapping>
    <filter-name>CAS Authentication Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Validation Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
</context-param>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
    <display-name>Pagina di user</display-name>
    <web-resource-collection>
        <web-resource-name>index1</web-resource-name>
        <description>ristretto a user</description>
        <url-pattern>/faces/index.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <description>user only</description>
        <role-name>AMP-User</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <display-name>Pagina di profile</display-name>
    <web-resource-collection>
        <web-resource-name>index2</web-resource-name>
        <description>risretto a profile</description>
        <url-pattern>/faces/index_2.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <description>profile only</description>
        <role-name>AMP-Profile</role-name>
    </auth-constraint>
</security-constraint>
<security-role>
    <description>utente generico</description>
    <role-name>AMP-User</role-name>
</security-role>
<security-role>
    <description>Utente di alto profilo</description>
    <role-name>AMP-Profile</role-name>
</security-role> 

I've then assigned the roles to my LDAP groups in glassifh-web.xml

    <glassfish-web-app error-url="">
  <security-role-mapping>
    <role-name>AMP-Profile</role-name>
    <group-name>AMP-Profile</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>AMP-User</role-name>
    <group-name>AMP-User</group-name>
  </security-role-mapping>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</glassfish-web-app>

The problem is that when I access to the page index.xhtml a form is asking me to authenticate but the authentication should be done by the CAS server. Anyway I cannot authenticate. How can I use CAS authentication and map LDAP groups to roles?

1
So do you want to use glassfish for authentication or authorization at all? Or is the CAS server (via those filter elements) supposed to block unauthenticated requests? You did ask the glassfish server to restrict access to those index pages by specifying the security constraints for them. As you did not supply a authentication method, I guess it defaults to basic authentication. Perhaps you could remove those constraints and let the CAS server do its thing.TPete
CAS should block unauthenticated request. Furthermore CAS or Glassfish should block authenticated request but with not allowed role. Is that possible? I removed the constraint but no authorization is performed so any LDAP group can access after authentication.maxqua72
So authentication using the CAS server already works when removing the security constraint?TPete
yes, authentication works. The issue is on authorization...maxqua72

1 Answers

0
votes

You can use the security annotations (JSR 250, javax.security.annotations), to define role based access control:

@Stateless
@DeclareRoles({"admin", "users"})
public class HelloEJB implements Hello {
    @PermitAll
    public String hello(String msg) {
        return "Hello, " + msg;
    }

    @RolesAllowed("admin")
    public String bye(String msg) {
         return "Bye, " + msg;
    }
}

Slightly adapted example from the first link below

Here I declared the roles first, using @DeclareRoles. @PermitAll grants access to all authenticated users, while @RolesAllowed only grants access to the mentioned roles.

You will need to set up roles in your deployment descriptors and in glassfish as well. I found this article very helpful. The Glassfish Server Security Guide goes through the details. You also might want to check out this question. If you run into some problems, ask back here on SO.