<title>Security Configuration</title>

<objsummary/>

<example>
&lt;http-server>
  &lt;!-- Resin DBPool for the JdbcAuthenticator -->
  &lt;resource-ref>
    &lt;res-ref-name>jdbc/auth&lt;/res-ref-name>
    &lt;res-type>javax.sql.DataSource&lt;/res-type>
    &lt;init-param driver-name="org.gjt.mm.mysql.Driver"/>
    &lt;init-param url="jdbc:mysql://localhost:3306/test"/>
  &lt;/resource-ref>
     
  &lt;login-config auth-method='form'>
    &lt;form-login-config>
      &lt;form-login-page>/login.html&lt;/form-login-page>
      &lt;form-error-page>/error.html&lt;/form-error-page>
    &lt;/form-login-config>
    
    &lt;!-- Resin-specific JdbcAuthenticator -->
    &lt;authenticator id='com.caucho.server.http.JdbcAuthenticator'>
      &lt;password-query>
        SELECT password FROM LOGIN WHERE username=?
      &lt;/password-query>
    &lt;/authenticator>
  &lt;/login-config>
&lt;/http-server>
</example>

<section name='login-config' title='web-app/login-config'>

<defun name=auth-method title='auth-method'>
<sum>Selects the authentication method.</sum>

<deftable>
<tr><td>basic<td>HTTP Basic authentication
<tr><td>form<td>Form-based authentication
</deftable>

</defun>

<defun name=form-login-config title='form-login-config'>
<sum>Configures authentication for forms.</sum>  The login form has
specific parameters that the servlet engine's login form processing
understands.  If the login succeeds, the user will see the original
page.  If it fails, she will see the error page.

<deftable>
<tr><td>form-login-page<td>The page to be used to prompt the user login<td>none
<tr><td>form-error-page<td>The error page for unsuccessful login<td>none
<tr><td>internal-forward<td>Use an internal redirect on success or a sendRedirect<td>false
<tr><td>form-uri-priority<td>If true, the form's j_uri will override a stored URI<td>false
</deftable>

<p/>The form itself must have the action <var/j_security_check/>.  It
must also have the parameters <var/j_username/> and <var/j_password/>.
Optionally, it can also have <var/j_uri/> and
<var/j_use_cookie_auth/>.  <var/j_uri/> gives the next page to display
when login succeeds.  <var/j_use_cookie_auth/> allows Resin to send a
persistent cookie to the user to make following login easier.

<p/><var/j_use_cookie_auth/> gives control to the user whether to generate
a persistent cookie.  It lets you implement the "remember me" button.  By
default, the authentication only lasts for a single session.

<deftable>
<tr><td>j_security_check<td>The form's mandatory action
<tr><td>j_username<td>The user name
<tr><td>j_password<td>The password
<tr><td>j_uri<td>Optional Resin extension for the successful display page.
<tr><td>j_use_cookie_auth<td>Optional Resin extension to allow cookie login.
</deftable>

<p/>The following is an example of a servlet-standard login page:

<example>
&lt;form action='j_security_check' method='POST'>
&lt;table>
&lt;tr>&lt;td>User:&lt;td>&lt;input name='j_username'>
&lt;tr>&lt;td>Password:&lt;td>&lt;input name='j_password'>
&lt;tr>&lt;td colspan=2>hint: the password is 'quidditch'
&lt;tr>&lt;td>&lt;input type=submit>
&lt;/table>
&lt;/form>
</example>

</defun>

</section>

<section name=authenticator title='authenticator' version='Resin 1.1'>
<sum>Specifies a class to authenticate users.</sum>  This Resin-specific
option lets you control your authentication.  You can either create your 
own custom authenticator, or use Resin's JdbcAuthenticator.

<p/>The authenticator is responsible for taking the username and
password and returning a UserPrincipal if the username and password match.

<p/>Users wanting to implement an authenticator should look at the JavaDoc
for <a href="../javadoc/com/caucho/http/security/ServletAuthenticator.html">ServletAuthenticator</a>
and <a href="../javadoc/com/caucho/http/security/AbstractAuthenticator.html">AbstractAuthenticator</a>.
To protect your application from API changes, you should extend
AbstractAuthenticator rather than implementing Authenticator directly.

<subsection title='JdbcAuthenticator' version='Resin 2.0'>
<p/>The JdbcAuthenticator (com.caucho.http.security.JdbcAuthenticator),
asks a backend database for the password matching the user's name.
It uses the DataSource specified by the <var/pool-name/> option, or
the JNDI <var/java:comp/env/jdbc/db-pool/> by default.
<var/pool-name/> refers to a DataSource configured with
<a href="app-config.xtp#resource-ref">resource-ref</a>.

<p/>The following are the attributes for the JdbcAuthenticator:

<deftable>
<tr><td>pool-name<td>The database pool.  Looks in the application
attributes first, then in the global database pools.
<tr><td>password-query<td>A SQL query to get the user's password.  The
default query is given below.
<tr><td>cookie-auth-query<td>A SQL query to authenticate the user by a
persistent cookie.
<tr><td>cookie-auth-update<td>A SQL update to match
a persistent cookie to a user.
<tr><td>role-query<td>A SQL query to determine the user's role.  By
default, all users are in role "user", but no others.
<tr><td>password-digest<td>Specifies the digest algorithm and format (Resin 2.0.4)
</deftable>

<example>
&lt;!-- Resin-specific JdbcAuthenticator -->
&lt;authenticator id='com.caucho.http.security.JdbcAuthenticator'>
  &lt;pool-name>test&lt;/pool-name>
  &lt;password-query>
    SELECT password FROM LOGIN WHERE username=?
  &lt;/password-query>
  &lt;cookie-auth-query>
    SELECT username FROM LOGIN WHERE cookie=?
  &lt;/cookie-auth-query>
  &lt;cookie-auth-update>
    UPDATE LOGIN SET cookie=? WHERE username=?
  &lt;/cookie-auth-update>
  &lt;role-query>
    SELECT role FROM LOGIN WHERE username=?
  &lt;/role-query>
&lt;/authenticator>
</example>

</subsection>

<subsection title='PasswordDigest' version='Resin 2.0.4'>

Resin 2.0.4 adds the capability to store the digest of
a password instead of the password itself.  By using the password digest,
the application can avoid storing the password in a form that someone
can read.

<p/>Setting password-digest of any authenticator
extending AbstractAuthenticator will create a digest of the password.
The password-digest has two parts: the digest algorithm
and the encoding format.  "MD5-base64" is a typical digest format.

<p/>The authenticator will create a digest of the username and password.
Since that digest is a byte array, it is then converted to a string.
<def>
MD5(<var/username/>:<var/password/>)
</def>

<example title='Using password-digest with XmlAuthenticator'>
&lt;authenticator>
  &lt;class-name>com.caucho.http.security.XmlAuthenticator&lt;/class-name>
  &lt;init-param password-digest='MD5-base64'/>
  &lt;init-param user='harry:Syvian7bcPDKI261QvH9Cw:user'/>
&lt;/authenticator>
</example>

<p/>Of course, storing the digest password take a bit more work.  When
the user registers, the application needs to compute the
digest to store it.  You can use the PasswordDigest class to do that.

<example>
import com.caucho.http.security.PasswordDigest;

...
PasswordDigest digest = new PasswordDigest();
digest.setAlgorithm("MD5");
digest.setFormat("base64");

String password = digest.getDigestPassword("harry", "quidditch");
</example>

</subsection>

</section>

<section title='Authorization (security-constraint)'>

<defun name=security-constraint title='security-constraint'>
<sum>Selects protected areas of the web site.</sum>  Sites using
authentication as an optional personalization feature will typically
not use any security constraints.

<p/>Security constraints can also be custom classes.

<example>
&lt;security-constraint>
  &lt;web-resource-collection>
    &lt;url-pattern>/*&lt;/url-pattern>
  &lt;/web-resource-collection>
  &lt;auth-constraint role-name='user'>
&lt;/security-constraint>
</example>
</defun>

<defun name=web-resource-collection
       title='web-resource-collection'>
<sum>Specifies a collection os areas of the web site.</sum>

<deftable>
<tr><td>url-pattern<td>url patterns describing the resource
<tr><td>method<td>HTTP methods to be restricted.
</deftable>
</defun>

<defun name=auth-constraint
       title='auth-constraint'>
<sum>Requires that authenticated users fill the specified role.</sum>
In Resin's JdbcAuthenticator, normal users are in the "user" role.
Think of a role as a group of users.

<deftable>
<tr><td>role-name<td>Roles which are allowed to access the resource.
</deftable>

</defun>

<defun name=user-data-constraint
       title='user-data-constraint'>
<sum>Restricts access to secure transports, i.e. SSL</sum>

<deftable>
<tr><td>transport-guarantee<td>Required transport properties.  NONE,
INTEGRAL, and CONFIDENTIAL are allowed values.
</deftable>

</defun>

<defun title='constraint'>
<sum>Defines a custom constraint</sum>  The custom constraint specifies
a <var/&lt;class-name>/> which extends
com.caucho.http.security.AbstractConstraint.  Any <var/init-param/>
elements use Bean introspection to initialize the constraint.

<example>
...
&lt;security-constraint>
  &lt;constraint>
    &lt;class-name>qa.CustomSecurity&lt;/class-name>
    &lt;init-param foo='ok'/>
  &lt;/constraint>
  &lt;web-resource-collection url-pattern='/*'/>
&lt;/security-constraint>
...
</example>

</defun>

<subsection title='Custom Security Constraints'>

Any custom security constraint is checked after any authentication (login)
but before any filters or servlets are applied.  The security constraint will
return true if the request is allowed and false if it's forbidden.  If the
request is forbidden, it's the constraint's responsibility to return an
error page.

<example>
package qa;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.caucho.http.security.*;

public class CustomSecurity extends AbstractConstraint {
  private String foo = "false";

  public void setFoo(String foo)
  {
    this.foo = foo;
  }

  public boolean isAuthorized(HttpServletRequest request,
                              HttpServletResponse response,
                              ServletContext application)
    throws ServletException, IOException
  {
    if (foo.equals(request.getParameter("test")))
      return true;

    response.sendError(response.SC_FORBIDDEN);

    return false;
  }
}
</example>

</subsection>

</section>
