type=page
status=published
title=Using Programmatic Security with Web Applications
next=security-webtier004.html
prev=security-webtier002.html
~~~~~~
Using Programmatic Security with Web Applications
=================================================

[[GJIIE]]

[[using-programmatic-security-with-web-applications]]
Using Programmatic Security with Web Applications
-------------------------------------------------

Programmatic security is used by security-aware applications when
declarative security alone is not sufficient to express the security
model of the application.

The following topics are addressed here:

* link:#GIRCJ[Authenticating Users Programmatically]
* link:#BNCBA[Checking Caller Identity Programmatically]
* link:#GJJLQ[Example Code for Programmatic Security]
* link:#BNCBB[Declaring and Linking Role References]

[[GIRCJ]]

[[authenticating-users-programmatically]]
Authenticating Users Programmatically
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following methods of the `HttpServletRequest` interface enable you
to authenticate users for a web application programmatically.

* `authenticate` allows an application to instigate authentication of
the request caller by the container from within an unconstrained request
context. A login dialog box displays and collects the user name and
password for authentication purposes.
* `login` allows an application to collect user name and password
information as an alternative to specifying form-based authentication in
an application deployment descriptor.
* `logout` allows an application to reset the caller identity of a
request.

The following example code shows how to use the `login` and `logout`
methods:

[source,oac_no_warn]
----
package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name="TutorialServlet", urlPatterns={"/TutorialServlet"})
public class TutorialServlet extends HttpServlet {
    @EJB
    private ConverterBean converterBean;

    /**
     * Processes requests for both HTTP <code>GET</code> 
     *    and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, 
            HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet TutorialServlet</title>");
            out.println("</head>");
            out.println("<body>");
            request.login("TutorialUser", "TutorialUser");
            BigDecimal result = 
                converterBean.dollarToYen(new BigDecimal("1.0"));
            out.println("<h1>Servlet TutorialServlet result of dollarToYen= "
                + result + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } catch (Exception e) {
            throw new ServletException(e);
        } finally {
            request.logout();
            out.close();
        }
    }
}
----

The following example code shows how to use the `authenticate` method:

[source,oac_no_warn]
----
package com.example.test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class TestServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, 
            HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            request.authenticate(response);
            out.println("Authenticate Successful");
        } finally {
            out.close();
        }
    }
----

[[BNCBA]]

[[checking-caller-identity-programmatically]]
Checking Caller Identity Programmatically
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In general, security management should be enforced by the container in a
manner that is transparent to the web component. The security API
described in this section should be used only in the less frequent
situations in which the web component methods need to access the
security context information.

Servlet 4.0 specifies the following methods that enable you to access
security information about the component's caller.

* `getRemoteUser` determines the user name with which the client
authenticated. The `getRemoteUser` method returns the name of the remote
user (the caller) associated by the container with the request. If no
user has been authenticated, this method returns `null`.
* `isUserInRole` determines whether a remote user is in a specific
security role. If no user has been authenticated, this method returns
`false`. This method expects a `String` user `role-name` parameter.
+
The `security-role-ref` element should be declared in the deployment
descriptor with a `role-name` subelement containing the role name to be
passed to the method. Using security role references is discussed in
link:#BNCBB[Declaring and Linking Role References].
* `getUserPrincipal` determines the principal name of the current user
and returns a `java.security.Principal` object. If no user has been
authenticated, this method returns `null`. Calling the `getName` method
on the `Principal` returned by `getUserPrincipal` returns the name of
the remote user.

Your application can make business-logic decisions based on the
information obtained using these APIs.

[[GJJLQ]]

[[example-code-for-programmatic-security]]
Example Code for Programmatic Security
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following code demonstrates the use of programmatic security for the
purposes of programmatic login. This servlet does the following.

1.  It displays information about the current user.
2.  It prompts the user to log in.
3.  It prints out the information again to demonstrate the effect of the
`login` method.
4.  It logs the user out.
5.  It prints out the information again to demonstrate the effect of the
`logout` method.

[source,oac_no_warn]
----
package enterprise.programmatic_login;

import java.io.*;
import java.net.*;
import javax.annotation.security.DeclareRoles;
import javax.servlet.*;
import javax.servlet.http.*;

@DeclareRoles("javaeeuser")
public class LoginServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP GET and POST methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, 
                 HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String userName = request.getParameter("txtUserName");
            String password = request.getParameter("txtPassword");
            
            out.println("Before Login" + "<br><br>");
            out.println("IsUserInRole?.." 
                        + request.isUserInRole("javaeeuser")+"<br>");
            out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
            out.println("getUserPrincipal?.." 
                        + request.getUserPrincipal()+"<br>");
            out.println("getAuthType?.." + request.getAuthType()+"<br><br>");
            
            try {
                request.login(userName, password); 
            } catch(ServletException ex) {
                out.println("Login Failed with a ServletException.." 
                    + ex.getMessage());
                return;
            }
            out.println("After Login..."+"<br><br>");
            out.println("IsUserInRole?.." 
                        + request.isUserInRole("javaeeuser")+"<br>");
            out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
            out.println("getUserPrincipal?.." 
                        + request.getUserPrincipal()+"<br>");
            out.println("getAuthType?.." + request.getAuthType()+"<br><br>");
            
            request.logout();
            out.println("After Logout..."+"<br><br>");
            out.println("IsUserInRole?.." 
                        + request.isUserInRole("javaeeuser")+"<br>");
            out.println("getRemoteUser?.." + request.getRemoteUser()+"<br>");
            out.println("getUserPrincipal?.."
                        + request.getUserPrincipal()+"<br>");
            out.println("getAuthType?.." + request.getAuthType()+"<br>");
        } finally {
            out.close();
        }
    }
    ...
}
----

[[BNCBB]]

[[declaring-and-linking-role-references]]
Declaring and Linking Role References
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A security role reference is a mapping between the name of a role that
is called from a web component using `isUserInRole(String role)` and the
name of a security role that has been defined for the application. If no
`security-role-ref` element is declared in a deployment descriptor and
the `isUserInRole` method is called, the container defaults to checking
the provided role name against the list of all security roles defined
for the web application. Using the default method instead of using the
`security-role-ref` element limits your flexibility to change role names
in an application without also recompiling the servlet making the call.

The `security-role-ref` element is used when an application uses the
`HttpServletRequest.isUserInRole(String role)`. The value passed to the
`isUserInRole` method is a `String` representing the role name of the
user. The value of the `role-name` element must be the `String` used as
the parameter to the `HttpServletRequest.isUserInRole(String role)`. The
`role-link` must contain the name of one of the security roles defined
in the `security-role` elements. The container uses the mapping of
`security-role-ref` to `security-role` when determining the return value
of the call.

For example, to map the security role reference `cust` to the security
role with role name `bankCustomer`, the elements would look like this:

[source,oac_no_warn]
----
<servlet>
...
    <security-role-ref>
        <role-name>cust</role-name>
        <role-link>bankCustomer</role-link>
    </security-role-ref>
...
</servlet>
----

If the servlet method is called by a user in the `bankCustomer` security
role, `isUserInRole("cust")` returns `true`.

The `role-link` element in the `security-role-ref` element must match a
`role-name` defined in the `security-role` element of the same `web.xml`
deployment descriptor, as shown here:

[source,oac_no_warn]
----
<security-role>
    <role-name>bankCustomer</role-name>
</security-role>
----

A security role reference, including the name defined by the reference,
is scoped to the component whose deployment descriptor contains the
`security-role-ref` deployment descriptor element.


