Authentication in Tomcat and Sessions in Cocoon
R. Alexander Milowski
milowski@sims.berkeley.edu
School of Information Management and Systems
#1
Terms
Authentication - identifies "who you are" (e.g. username and password, public/private keys).
Authorization - an identification of "what you are allowed to do" (e.g. user is an administrator).
Session - a time period during which a user is authenticated and may have information associated with it.
#2
Servlets, J2EE, & Authentication
J2EE/Servlets provides:
HTTP Basic Authentication
Form-based Authentication
Client-Certificate Authentication
Tomcat implements/provides these in some way...
Your application should work just fine in other Servlet containers (e.g. BEA, WebSphere, etc.).
#3
What Tomcat Provides
Tomcat has both Authentication and Authorization.
It can have many different back-end systems:
Simple XML file containing the user/passwords & roles.
JNDI/LDAP
Relational Databases
The "role" allows simple authorization-to-user assocations.
#4
The "Simple" & "Insecure" Way
There is a file in "conf/tomcat-users.xml" that contains:
Username and passwords.
Authorization roles.
User/Role Associations.
Just add entries to this file and restart Tomcat.
An example:
<tomcat-users> <role rolename="tomcat"/> <role rolename="eventuser"/> <role rolename="manager"/> <role rolename="admin"/> <user username="jimmy" password="jimmy" roles="eventuser"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="admin" password="admin" roles="admin,manager"/> </tomcat-users>
The password can be encrypted (see next slide).
#5
The Tomcat server.xml
The user database is configured in the 'conf/server.xml' file.
Read the configurtion manual.... but quickly...
This defines the database file:
<Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"> </Resource> <ResourceParams name="UserDatabase"> <parameter> <name>factory</name> <value>org.apache.catalina.users.MemoryUserDatabaseFactory</value> </parameter> <parameter> <name>pathname</name> <value>conf/tomcat-users.xml</value> </parameter> </ResourceParams>
The 'Realm' element declares what database should be used:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" debug="0" resourceName="UserDatabase"/>
If you want encrypted passwords (e.g. MD5), add a digest attribute:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" debug="0" resourceName="UserDatabase" digest="MD5"/>
Other 'Realm' elements let you use other "back-ends":
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://localhost/authority" connectionName="test" connectionPassword="test" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name" />
#6
Using Form Authentication - Step 1
Just add this to your web.xml:
<login-config> <auth-method>FORM</auth-method> <realm-name>myrealm</realm-name> <form-login-config> <form-login-page>login</form-login-page> <form-error-page>loginfailed</form-error-page> </form-login-config> </login-config>
Your form needs to have these inputs and action:
<form method="POST" action="j_security_check" > <input type="text" name="j_username" > <input type="password" name="j_password" > </form>
#7
Using Form Authentication - Step 2
You might want to constraint to a particular role.
Add this to the web.xml:
<security-role> <description>This is the role required for this application</description> <role-name>eventuser</role-name> </security-role>
#8
Using Form Authentication - Step 3
You need to say what resources need authentication.
If this is put in the web.xml, it protects the whole application:
<security-constraint> <web-resource-collection> <web-resource-name>Example Event Application</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>eventuser</role-name> </auth-constraint> </security-constraint>
#9
Cocoon Pipelines for Form Authentication
Just add the following:
<map:match pattern="login"> <map:read src="login.html" mime-type="text/html"/> </map:match> <map:match pattern="loginfailed"> <map:read src="loginfailed.html" mime-type="text/html"/> </map:match> <map:match pattern="logout"> <map:act type="session-invalidate"/> <map:act type="request"> <map:parameter name="parameters" value="true"/> <map:redirect-to uri="login"/> </map:act> </map:match>
#10
Sessions in Cocoon
Cocoon allows sessions to have XML documents associated with them.
Each document is named with a session context name.
You can create, updated, and delete the document's content and session contexts.
#11
Why?
You can use the session to store information between forms/pages.
It is an in-memory construct and is secure.
But you don't want to store a lot of information in these sessions...
...because that takes up too much memory.
#12
The Session Transformer
The session transformer in a pipeline manipulates the session.
You give it an input document:
<work xmlns:s="http://apache.org/cocoon/session/1.0"> <s:createcontext name="mystuff"/> <s:setxml context="mystuff" path="/"> <stuff/> </s:setxml> <s:getxml context="mystuff" path="/"/> </work>
And it does what you say.
#13
Get/Set Session Documents
Use 'createcontext' to create a named document:
<s:createcontext name="mystuff"/>
Use 'setxml' to update a document at an XPath expression's target:
<s:setxml context="mystuff" path="/"> <stuff/> </s:setxml>
Use 'getxml' to get content at an XPath expression's target:
<s:getxml context="mystuff" path="/"/>
#14
Updating Existing Session Documents
This adds the children at the XPath specified:
<work xmlns:s="http://apache.org/cocoon/session/1.0"> <s:createcontext name="mystuff"/> <s:setxml context="mystuff" path="/stuff/"> <child/> <child/> <child/> <child/> </s:setxml> <s:getxml context="mystuff" path="/"/> </work>
At the end, it retrieves the result.
#15
Built-in Sessions
There are built-in session context for things like the HTTP request.
This gets the remote user:
<user> <s:getxml xmlns:s="http://apache.org/cocoon/session/1.0" context="request" path= "/remoteUser"/> </user>
Check out the Cocoon documentation on the Session transformer.
#16
Pipelines for Sessions
These pipelines run two different session manipulations:
<map:match pattern="session"> <map:generate type="file" src="session.xml"/> <map:transform type="session"/> <map:serialize type="xml"/> </map:match> <map:match pattern="session-next"> <map:generate type="file" src="session-next.xml"/> <map:transform type="session"/> <map:serialize type="xml"/> </map:match>