AuthZ for Web Based Applications

This guide is still in draft status and will be completed soon.

The best way to get started until this guide is completed is to first go through, perform, and successfully complete the authZ for standalone apps example.

The javax.servlet.http.HttpServletRequest API is an interface that defines a method named isUserInRole. The SPNEGO Library implements that method. The SPNEGO Library also defines additional APIs as well as a reference implementation that allow for a more expressive authorization (authZ) scheme.

The SPNEGO Library authZ APIs attempts to be loosely-coupled but highly-cohesive with other authorization frameworks. This guide and the authZ for standalone apps example along with the LdapAccessControl reference implementation is an illustration of how the SPNEGO Library can use existing, user-defined, custom-built, authorization data stores (RDBMS, xml files, REST service, etc.) for checking user credentials (authZ).

Before Getting Started

In the authZ for standalone apps example, a spnego.policy file was modified with parameter values that were specific to your environment. This guide will use that modified spnego.policy file from that example.

Be sure to complete that example before proceeding with this guide.

Also, if you don't already have a working app server that authenticates requests via Kerberos/SPNEGO, take a look at the installing Tomcat or installing JBoss example.

Authentication (authN) must be working as expected before proceeding with configuring the SPNEGO Library for authorization (authZ).

Finally, be sure to read the javadoc for the SpnegoAccessControl interface as well as the updated reference docs and the authZ section.

Summary:

In the authZ for standalone apps example, all of the configuration parameters must be specified in the spnego.policy file.

For web-based applications, some of the configuration parameters must be specified in the web.xml file as additional initial parameters to the servlet definition.

In addition, some of the authZ configuration parameters will use parameter values specified for authN as it's default value. e.g. username/password, etc.

Changes to the web.xml file

Here's an example configuration:

<filter>
    <filter-name>SpnegoHttpFilter</filter-name>
    <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>

    <-- autheNtication (authN) parameters -->
    <init-param>
        <param-name>spnego.allow.basic</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.allow.localhost</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.allow.unsecure.basic</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.client.module</param-name>
        <param-value>spnego-client</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.krb5.conf</param-name>
        <param-value>krb5.conf</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.conf</param-name>
        <param-value>login.conf</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.preauth.username</param-name>
        <param-value>Zeus</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.preauth.password</param-name>
        <param-value>Z3usP@55</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.server.module</param-name>
        <param-value>spnego-server</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.prompt.ntlm</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.logger.level</param-name>
        <param-value>1</param-value>
    </init-param>

    <-- authoriZation (authZ) parameters -->
    <init-param>
        <param-name>spnego.authz.class</param-name>
        <param-value>net.sourceforge.spnego.LdapAccessControl</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.ldap.url</param-name>
        <param-value>ldap://athena.local:389</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.policy.file</param-name>
        <param-value>C:/spnego-examples/spnego.policy</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.unique</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>

Notice that some of the values previously specified in the spnego.policy file is now specified in the web.xml file.

For more information on additional authZ parameters, refer to the authZ section of the reference docs.

Changes to the spnego.policy file

Since some of the authZ specific configuration parameters are now specified in the web.xml file, either explicitly or as default values taken from the authN configuration parameters, we will comment-out some of those parameters from the spnego.policy file.

Notice that the first six (6) lines of the spnego.policy file have now been commented-out.

Creating the hello_authz.jsp file

Download and modify the contents of the hello_authz.jsp file with values specific to your environment.


<%@ page import="net.sourceforge.spnego.*" %>

<%
    SpnegoAccessControl accessControl = null;
    if (request instanceof SpnegoAccessControl) {
         accessControl = (SpnegoAccessControl) request;
    } else {
        throw new Exception("Not an instance of SpnegoAccessControl");
    }
%>

<br >true = <%= accessControl.anyRole("IT") %>
<br >true = <%= accessControl.hasRole("IT") %>
<br >true = <%= accessControl.hasRole("IT","Marketing","HR") %>

<br >false = <%= accessControl.hasRole("HR","Marketing","IT") %>

<br >true = <%= accessControl.hasAccess("my-edit-button") %>

<br >false = <%= accessControl.hasAccess("my-hr-button") %>

<br>No java cast...
<br>true = <%= request.isUserInRole("IT") %>
<br>true = <%= request.isUserInRole("Marketing") %>
<br>false = <%= request.isUserInRole("HR") %>

Notice that authZ will only occur on this specific .jsp file since we did not configure the web.xml to do a user authZ check on every page request (site wide check).

Testing the hello_authz.jsp file

Place the hello_authz.jsp file on your app server, open a web browser and go to that page.

If everything works as expected, the output should looks similar to the screenshot below.

Enabling site-wide user authZ check

add the parameter spnego.authz.sitewide with a value of my-edit-button

to use a custom 403 Forbidden page instead of relying on the default browser behavior, create a landing page and specify the name of that page in the web.xml file

optional user-defined 403 Forbidden landing page, add the parameter spnego.authz.403 with a value of... path to custom page. e.g. /my-403-handler.jsp

if the spnego.authz.403 parameter is not specified in the web.xml file, the web browser uses it's default display message

refer to the authZ section of the reference docs

update web.xml file below

<filter>
    <filter-name>SpnegoHttpFilter</filter-name>
    <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>

    <-- autheNtication (authN) parameters -->
    <init-param>
        <param-name>spnego.allow.basic</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.allow.localhost</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.allow.unsecure.basic</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.client.module</param-name>
        <param-value>spnego-client</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.krb5.conf</param-name>
        <param-value>krb5.conf</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.conf</param-name>
        <param-value>login.conf</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.preauth.username</param-name>
        <param-value>Zeus</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.preauth.password</param-name>
        <param-value>Z3usP@55</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.login.server.module</param-name>
        <param-value>spnego-server</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.prompt.ntlm</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.logger.level</param-name>
        <param-value>1</param-value>
    </init-param>

    <-- authoriZation (authZ) parameters -->
    <init-param>
        <param-name>spnego.authz.class</param-name>
        <param-value>net.sourceforge.spnego.LdapAccessControl</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.ldap.url</param-name>
        <param-value>ldap://athena.local:389</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.policy.file</param-name>
        <param-value>C:/spnego-examples/spnego.policy</param-value>
    </init-param>
    <init-param>
        <param-name>spnego.authz.unique</param-name>
        <param-value>false</param-value>
    </init-param>

    <-- enable sitewide authZ -->
    <init-param>
        <param-name>spnego.authz.sitewide</param-name>
        <param-value>my-edit-button</param-value>
    </init-param>

    <-- optional but we specify anyway -->
    <init-param>
        <param-name>spnego.authz.403</param-name>
        <param-value>/my-403-handler.jsp</param-value>
    </init-param>
</filter>

Getting Information About the User

Lastly, the SPNEGO Library can obtain user information such as first name, last name, email, active directory groups, department, etc. and make that user information available to your web application or your standalone application via the getUserInfo method.

Take a look at the get user group info from LDAP guide for more information.

Links:
pre-flight checklist
install guide - tomcat
install guide - jboss
install guide - glassfish
enable authZ with LDAP
get user group info from LDAP
reference docs
api docs
download

Troubleshooting:
HelloKDC.java
hello_spnego.jsp
HelloKeytab.java
hello_delegate.jsp
SpnegoHelloClient.java
ExampleSpnegoAuthenticatorValve.java

Examples:
create keytab for client
create keytab for app server
credential delegation
protected SOAP Web Service
tomcat authenticator valve
jboss authenticator valve
authZ for standalone apps
protecting edit button on page

Licensing:
GNU LGPL


© 2009 Darwin V. Felix. All rights reserved.