|
Using Form Based Authentication
It's quite easy to setup and use form-based authentication for Web applications running on OC4J. Here's how you do it.
The example to go along with this can be found here.
1. Add custom login and error pages to your Web application.
These are simple JSPs, which contain a form to allow a user to enter a
username/password. When the submit button is pressed, the values are
sent off to a special handler servlet containers implement to
authenticate users in the form based authentication model. If the supplied user is authenticated, then the
originally requested URL is loaded. If the authentication fails, the
error page is shown.
Note: you must use the exact values shown in the form below for the form action, the username and password fields.
Here's a working example of a login.jsp page
<html>
<head>
<title>Login Page for Example FormBasedAuth</title>
</head>
<body bgcolor="white">
<h2>Custom Login Page</h2>
<hr>
<!--
This is the custom logon page. You must use the exact action and form field names
for a custom logon page.
-->
<form method="POST" action="j_security_check">
<table border="0" cellspacing="5">
<tr>
<th align="right">Username:</th>
<td align="left"><input type="text" name="j_username"></td>
</tr>
<tr>
<th align="right">Password:</th>
<td align="left"><input type="password" name="j_password"></td>
</tr>
<tr>
<td align="right"><input type="submit" value="Login"></td>
<td align="left"><input type="reset"></td>
</tr>
</table>
</form>
</body>
</html>
The error.jsp page would look very similar.
Perhaps with the addition of some text to indicate that the logon
wasn't successful. Since these pages are JSPs, you can make them look
however you need to -- images, text, colors -- whatever.
It's your logon page.
The logon and error pages need to be put into your web application so
they can be loaded by the servlet container when necessary.
A good place to put them so they aren't directly accessible to clients (which they shouldn't be!) is in the /WEB-INF directory.
2. Create a protection scheme for your Web application.
Once you have these pages, you need to configure a security constraaint
for a set of resources within the Web application. This basically
involves specifying a URL pattern to be protected, definining with
authentication method is used to get the user to log on, and specifying
a logical user role which is allowed access to the protected resources.
This is all done in the WEB-INF/web.xml file.
First up, lets define the security constraint -- forgive the colors, I
was trying to make the sections easily distringuished and the color
palette is quite limited.
<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Pages</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>FunkyUser</role-name>
</auth-constraint>
</security-constraint>
The tags in purple indicate that we are adding a security constraint for the Web application.
The tags in blue define a protected resource, providing a description
and indicating which HTTP methods the protection should apply to.
The tag in red defines the URL of this specific Web context that this
protection applies to. In this case, any page requested within the Web
application will be protected and require the user to be authenticated
before running.
The tags in green define the logical security role that a supplied user
must belong to in order to access the protected resource. The
role-name used here is completely up to you, it does not need to map to
any specific security roles defined at the J2EE container level.
There must however be a corresponding entry in the web.xml file that
actually defines this role-name for the application. See step 4 for
more details.
3. Define a login configuration.
This steps basically tells the container how users are to sign on when
needing to authenticate to access a protectec resource. This is
where we tell the servlet container that it needs to use your custom
logon and error pages. There are several other options for this; BASIC,
FORM, CLIENT-CERT with each serving a slightly differnet role. If
you used the BASIC method, this results in the browser popping up a
dialog box to let users enter a username and password.
Since you want to use a custom logon page, you need to specify the FORM
option, and specify the resources to use to for the logon and error
pages.
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/web-inf/login.jsp</form-login-page>
<form-error-page>/web-inf/error.jsp</form-error-page>
</form-login-config>
</login-config>
The blue tags specify which authentication method should be used. For custom form based logon, set it to FORM..
The green tags specify the details for the form authentication
method. Here you specify the resources to for the login page, and
the error page. Note here how the path is set to load the pages from
the WEB-INF directory. This serves two handy purposes -- 1) it protects
your logon/error pages from direct client access; nothing from the
WEB-INF directory is accessible to clients via a direct URL, and 2) it
allows you to easily protect the root of your Web application.
4. Define a logical security role-name
Here you are actually declaring the logical security role-name that you
used in the step 2 in the security-constraint setting to indicate who
is allowed access to the protected resources.
A logical security role-name is just that -- it allows you as a
developer to specify protection schemes for resources, without knowing
the actual security roles that will exist on the production
server. This makes your application portable and not tied to any
one specific environment.
You can pretty much choose any name you want for your logical
roles. The important thing as far as the web.xml file goes is
that the name you choose for the logical role-name here
<security-role>
<description>A Funky User</description>
<role-name>FunkyUser</role-name>
</security-role>
For improved clarity, this security-role tag step could have
been listed here before the security contrainst step since it's defines
something used later -- but I just replicated what was in my web.xml
file......
5. The completed web.xml file.
At this point, you're done with the web.xml file. Here's a
complete example of the file so you can see where the elements all fit.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--
Define a security constraint and tell it which abstract roles are
permitted to access this resource
-->
<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>FunkyUser</role-name>
</auth-constraint>
</security-constraint>
<!-- Default a login configuration that uses form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/web-inf/login.jsp</form-login-page>
<form-error-page>/web-inf/error.jsp</form-error-page>
</form-login-config>
</login-config>
<!-- Define a logical role for this application, needs to be mapped to an actual role at deployment time -->
<security-role>
<description>A Funky User</description>
<role-name>FunkyUser</role-name>
</security-role>
</web-app>
Now I hear you asking, if the logical role-name
defines who can access the protected resources, how on earth do I fit
my actual users into that?
"That's a good question 99" -- bit of Max Smart there ...
6. Map the logical role-name to an actual security role from OC4J
With OC4J (and all J2EE containers I presume) the administrator can
setup lists of actual users with real usernames and passwords. These
are defined in XML files, or in some cases stored in LDAP
directories. These real users are typically assigned into groups
or roles. If you look at your OC4J installation, you can see an
example of this in the j2ee/home/config/jazn-data.xml file. This is a
default repository of users that are available to your OC4J instance.
So what we really need to do is tell OC4J how to map the logical
role-name defined in the Web application, to an actual set of users
available on OC4J. OC4J will then be able to join the dots, and
validate the logon details entered by a user against the actual user
repository, also ensuring that the specified username belongs in the
required actual role.
To perform this mapping, you use an OC4J specific deployment descriptor
-- for a Web application, this is a file called orion-web.xml.
Now there are a couple of ways you can go from here. I'll try and explain them.
6a Modify the generated orion-web.xml
Everytime an application is deployed, OC4J generates it's own set
of XML deployment descriptors which contain settings that apply
specifically to it. These are additional to the standard J2EE
deployment descriptors.
By default, the OC4J deployment descriptors are put into the
j2ee/home/config/application-deployments/<app-name>/<web-module>
directory, where app-name and web-module are the names from your actual
application being deployed.
Once you've deployed your web application, you can find the
orion-web.xml file which gets generated for your web module. Opening it
in an editor, you should that OC4J has noticed the definition of the
logical role in the web.xml file, so it has generated a section to
allow you to specify the mapping.
<orion-web-app ...>
<security-role-mapping name="FunkyUser">
<group name="" />
</security-role-mapping>
</orion-web-app>
The security-role-mapping tags allows you to map the
logical role-name from web.xml to an actual group/role from the OC4J
user repository.
So all you need to do to get this to work is add the name of an actual
role from the OC4J user repository to the group tag.
<orion-web-app ...>
<security-role-mapping name="FunkyUser">
<group name="administrators" />
</security-role-mapping>
</orion-web-app>
For simple testing purposes, you can always
use the "administrators" role since this is always defined in the OC4J
instance. This lets you logon to the Web application using the
administration user (admin/welcome by default) for your OC4J
instance. If you've modified the admin password using the
-install option of OC4J, then enter that password instead.
6b Provide the mapping in the WAR file
The second option is to provide the orion-web.xml file, preconfigured
within the WAR file you are deploying. This can be done quite simply by
creating the skeleton of the orion-web.xml file with the elements you
with to map, and putting it in the /WEB-INF directory alongside the
standard J2EE web.xml file.
When you deploy the WAR file, OC4J will notice the orion-web.xml file
that is supplied and will use this as a template when it generates the
actual file it uses as described in step 6a.
Providing the file with the orion-web.xml file with the application is
a useful tip when you specifically know which actual roles and groups
you need to map the Web application to. It saves you from needing
to make post deployment configurations, which is very handy when you
are testing out things in development.
Here is an example of a orion-web.xml which is included within the WAR file and which supplies the mapping for the logical role.
<orion-web-app>
<security-role-mapping name="FunkyUser">
<group name="administrators"/>
</security-role-mapping>
</orion-web-app>
This contains just the bare essentials -- OC4J will
generate all the other necessary tags and attributes it requires in
this file when the application is deployed.
Summary
So that's all there is to it. Create some JSP pages to gather
user logon details, tell the servlet container that you're using form
based auth for a specific set of resources, give a logical security
role permission to access the resources and finally tell OC4J which of
it's actual groups map into the logical role.
I have a zip file HERE you can download which
provides the full source code of a simple example using
form-based-authentication, mapping the users to the OC4J
"administrators" group.
It has a prebuilt EAR file which can be deployed immediately to your
OC4J instance, or you can use the supplied Ant script to rebuild the
application and deploy it to a local OC4J instance.'
The prebuilt EAR file is in the build directory. Deploy it using admin.jar or however you usually deploy applications.
To rebuild the source code, use the app target
>ant app
To deploy the application to a local OC4J instance
>ant bind-web-app
Be sure to check the property settings at the top of the build.xml file to make sure they correspond to your environment.
To access the application use the URL
http://localhost:8888/fba
This should present you with the custom login page.
© Copyright 2004 buttso.
Last update: 4/23/2004; 3:46:51 PM.
|
|