Chapter 9 Keeping Things Secure

Security is a topic that usually gets more attention than the topic of performance, but of course, the stakes are higher. Slow performance means unhappy customers or end users; poor security can have much more dire consequences. This chapter looks at security in several different ways, both from a WebSphere perspective using built-in security functionality, and from the viewpoint of application architecture and how you can build security into your applications where required.

Security from a code perspective should be a first line of defense. Applications need to be written securely, reviewed, and tested, to ensure that you are not allowing large security holes into your application and potentially into your enterprise. Common security attacks are around cross-side scripting and SQL injection. This chapter looks at SQL injection and provides some insight into how you can avoid that kind of attack.

In addition to securing your code, you can also use WebSphere Application Server, which provides several different mechanisms to help secure your application. Many project teams use their own security scheme not knowing or understanding how WAS security actually works. This chapter will look at enabling WAS security and applying it to your application.

Why Security Is Important

I am sure I don't really have to answer the question of why security is important. In today's IT world not understanding the risks and attacks that take place against us on a daily basis is almost impossible. Just look at our desktop machines pummeled by mal-ware constantly, in the same way Web sites are being assessed and attacked at a constant rate by intruders looking for weaknesses, or ways to get inside the system to steal data, or to plant their own information that can be used to attack other sites.

Beyond this type of attack, security also includes events of nonprofessional hackers who can sometimes cause problems. Think about a scenario where one employee simply by changing an ID within a home page could see another employee's personnel information. A simple example is shown in Figure 9.1 where a change in the query string will result in displaying a different employee's contact information.

Image

Figure 9.1 Example query string manipulation

The same effect can be caused by changing hidden values within a form, or even cookie data that is being stored by the application on the local browser. The application shown in Figure 9.1 is actually designed as an open people search application, so manipulating the query string does not do any real damage. But the example being discussed is relevant as other applications may not have the same open requirements.

The threats on the front end are many, and the challenge of ensuring security is becoming greater all the time as new attacks are being developed and perfected constantly. The truth is that keeping up on the latest security threats is very hard for the average programmer, so you need to look to experts or perhaps tooling to keep the threat information current and relevant to the organization and specific applications.

The Role of the Security Architect

Image

Many organizations would do well to create the role of a security architect within the organization. This specialized type of role would need to have broad skills within the realm of enterprise security and also some responsibility for ensuring that applications within the organization are secure. Figure 9.2 illustrates this role within the overall role of architects in the organization.

Image

Figure 9.2 Security architect role

The security architect would be in a good position to guide development teams on the predefined roles that are available within the organization and how those can be mapped to required functionality. Additionally, the security architect should be able to provide some formal review or testing on potential security flaws within the design or completed application. The development team cannot always keep up with the latest attacks but a security expert tasked with keeping the organization safe from these attacks can help guide the team in the right direction. The security architect can assist the entire organization by creating checklists and internal documents that outline the security standards for the development team. For example, common security standards may include ensuring that all user input is validated to help protect against SQL injection attacks.

Security protection within an application can be tricky. Many times instance variables within a servlet can cause some security issues. Security and session cookies that are not in sync can cause problems with shared computers; for example in a system on the shop floor where employees need to check and then sign up for health care benefits.

SQL Injection Example

Image

One common attack is that of using SQL injection to retrieve more information from the database than was originally intended. The central idea is to inject SQL into the application that is then run; the results are then displayed to the end user. Consider the screen in Figure 9.3. This form is designed to display some results based on the customer number that is submitted within the form.

Image

Figure 9.3 Customer lookup submit

The form itself is only a few lines that submits the entered data with a POST to the CustomerDetail servlet. All of the sample code is described in Appendix B, “Running the Examples,” along with the location for downloading the examples.

<form action="/SQLInjectionWebApp/CustomerDetail" method="post">
Customer Number: <input type="text" name="customerid" size="20">
<input type="submit" name="submit" value="Submit">
</form>

Once the customer number is submitted the servlet does an SQL query on the database and displays a few results from the customer table. For brevity this result set, shown in Figure 9.4, is very simple and only provides a few key pieces of information.

Image

Figure 9.4 Customer lookup results

The CustomerDetail servlet gets the customerid from the request and then submits it within an SQL call to the database.

String customerid = request.getParameter("customerid");
try {
   conn = ds.getConnection();
   stmt = conn.createStatement();


   query = "SELECT CUSTOMERNUMBER, CUSTOMERNAME, CREDITLIMIT FROM
DB2ADMIN.CUSTOMERS WHERE CUSTOMERNUMBER = " + customerid;


   rs = stmt.executeQuery(query);

The result set is written out directly to the browser by iterating through the result set and displaying each column in the set. Granted, this would not be the way production-ready code would be delivered, but you might be surprised the amount of code that requires this degree of flexibility.

  ResultSetMetaData rsmd = rs.getMetaData();
  int cols = rsmd.getColumnCount();


  while (rs.next()) {
   for (int i = 1; i <= cols; i++) {
   writer.print(rs.getString(i)+" ");
   writer.println();
   }
}

So what is the big deal? Well the big deal is in the way that the form input is directly injected into the SQL stream like so:

query = "SELECT CUSTOMERNUMBER, CUSTOMERNAME, CREDITLIMIT FROM
DB2ADMIN.CUSTOMERS WHERE CUSTOMERNUMBER = " + customerid;

This provides a security hole big enough to drive a truck through in many cases. All that a hacker has to do is perform a simple test to see whether this application is vulnerable to an SQL injection attack. He or she would enter in the customer number field the value, 114 AND 1=1. Because 1 does equal 1, this equates to AND TRUE. This result is a valid SQL statement that can be evaluated by the database. If the results of the query are the same as before, that is, the application returns the same results as if 114 were entered by itself, then potentially the application is vulnerable to an SQL injection attack.

When a potential victim has been identified, then the real work begins. By looking at error messages and trying to understand the underlying data structure, a hacker can do much damage. After a while, the attacker determines that he or she can extract payment information from the application with the following injection code,

114 UNION SELECT CUSTOMERNUMBER, CHECKNUMBER, AMOUNT FROM
DB2ADMIN.PAYMENTS WHERE CUSTOMERNUMBER = 114,

resulting in the output shown in Figure 9.5.

Image

Figure 9.5 Results with SQL injection

One can see how dangerous this type of attack could become.

Protecting against SQL Injection Attacks

Validation of input values is the key to protecting against SQL injection attacks. Other ways exist to protect against these types of attacks, such as ensuring that information found in error messages does not provide the attacker with clues to your data and application structure. In this example, a simple line change would have provided some better protection. Validating that the data input is indeed a numeric value will strip out all the additional SQL that could be added in.

Short customerid = Short.valueOf(request.getParameter("customerid"));
//String customerid = request.getParameter("customerid");

Making this change will cause the servlet to throw an error when a non-numeric value is appended to the field value.

 [4/7/08 15:26:21:375 EDT] 00000030 WebApp        E [Servlet Error]-
[CustomerDetail]: java.lang.NumberFormatException:
For input string: "114 AND 1=1"
   at java.lang.NumberFormatException.forInputString(NumberFormatException.java:63)
   at java.lang.Integer.parseInt(Integer.java:490)
   at java.lang.Short.parseShort(Short.java:135)
   at java.lang.Short.valueOf(Short.java:168)
   at java.lang.Short.valueOf(Short.java:193)

This is just one example of how an attack can occur. Someone in the organization has to be very diligent in keeping up with different types of attacks and how to protect against them as vulnerabilities occur. Using a persistence framework can also help, as validation often occurs as a part of that framework. To get more detail on persistence frameworks see Chapter 3, “Persistence Matters.”

imageWebSphere Security Basics

We skipped ahead a little at the beginning of this chapter in order to show an example of some of the security issues that can occur within applications. Computer Science 101 outlines a number of security functions that you should consider within application design. In this chapter we will look at two of them and how they fit within WebSphere Application Server. The two areas of consideration are

•   Authentication is the act of identifying users and ensuring that they are who they say they are. Is this really John Smith?

•   Authorization is the act of determining which permissions or access rights the user has on the system or application. Does John Smith have permission to view this data?

You need to consider many other areas when designing your application, such as transaction integrity, auditing, confidentiality, and nonrepudiation. These topics will need to be handled in a separate book. But there is more than enough to cover with authentication and authorization.

Authenticating Application Users

I actually still get surprised when I see applications that do not use WebSphere (WAS) security. Unauthenticated or public applications aside, many applications have used a home-grown security approach. This makes me uncomfortable for several reasons:

•   How secure is the application? Are there security holes in the approach that are unknown because no code or security review was done?

•   Did the team end up reinventing the wheel or in this case the security architecture? This is simply a waste of business value, unless a conscious decision was made not to use the provided framework.

•   How extensible is the custom security model? WebSphere security is designed to be pluggable with new capabilities as needed. For example, if a new single sign-on framework such as Tivoli Access Manager, or CA's SiteMinder was put into place, it could be incorporated into WAS security fairly easily.

Setting up application security within WebSphere is fairly simple, but does require some explanation. Figure 9.6 shows a variation of the WebSphere Security Management screen.

Image

Figure 9.6 WebSphere security setup

You can define different types of security within WAS, such as administrative security, application security, and Java 2 security, but setting up security requires a user registry to hold the user and group information needed by WebSphere to provide the security needed for authentication or authorization. Several different repositories are available:

•   Federated repository

•   Local operating system

•   Standalone Lightweight Directory Access Protocol (LDAP) registry

•   Standalone custom registry

Administrative security is enabled by default with a file-based federated repository configured as the main user repository. A simple way to check whether security is enabled is to use the snoop servlet. This servlet is part of the samples that are often deployed with a WebSphere profile. Security is one of those features that requires a restart of the application server. After the restart, navigate to the snoop servlet if it is installed and see whether you are prompted with a Basic Authentication prompt, as shown in Figure 9.7.

Image

Figure 9.7 Using basic authentication to access a Web resource

Using j_security_check

The web container provides a mechanism for protecting resources within your web application. Part of the servlet specification identifies the use of the j_security_check to provide a login process for your application. The use of j_security_check is available once application security is enabled within WebSphere.

You can identify the login form that is to be used by the security check within the web.xml of your application.

    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/login.jsp</form-login-page>
            <form-error-page>/loginError.jsp</form-error-page>
        </form-login-config>
    </login-config>

When a resource is protected, any call to that resource results in a redirect to the identified login page for authentication. The process is illustrated in Figure 9.8.

Image

Figure 9.8 j_security_check for forms-based login

Two parameters are required for use with j_security_check. Those parameters are j_username, and j_password. There should be no confusion about what those two parameters are used for. Here is an example of what your login.jsp should look like:

<form method="POST" action="j_security_check">


User ID:
<input type="text" name="j_username" id="name" maxlength="40">
Password:
<input type="password" name="j_password" id="pswd" maxlength="40">


<input type="submit" name="Submit" value="Log In">


</form>

As you can see in Figure 9.7, you should not actually link directly to the login.jsp. Rather let WAS do the redirecting as you try to go directly to some secured resource. The j_security_check login process will remember the URL that you originally tried to access, and will redirect you back to that URL after you have successfully logged in.

Securing Resources

One distinction that we have not made is that of roles versus groups within an application. The following definitions describe what they mean and how they work together:

•   Roles are generally defined by the application and can be organizational or functional roles such as HR manager or sales rep, or they can be application-specific roles, such as administrator.

•   Groups are generally defined within the user repository and may or may not map to application type of roles. Often an attempt is made to define groups that emulate roles within the organization, but more often than not, it is simply groups of users that need access to some application or function.

Although sometimes mapping groups to roles can be difficult, generally this separation provides the ability to create complex authorization mappings that fit the business need. Figure 9.9 shows an approach that is designed to allow for separation of concerns within the application development space, but that also provides the needed flexibility to work with most organizational security schemes.

Image

Figure 9.9 Role to group mapping

Role mappings can be done in many different ways, and many security practices often define the approach based on the organizational security model. Often roles are mapped to many groups within applications. For example, an editor role might be mapped to groups that contain managers, administrators, as well as actual editors.

You can see how this all fits together by looking at the web.xml from the sample FormLogon application. The application itself is pretty simple. It has two major functions: one for HR managers to view employee data, and one for sales reps to view customer data. Obviously the two areas should be separated so that a sales rep, for example, cannot look at other employee data. When started, the application displays a main menu (see Figure 9.10) for the user to choose which function he or she needs to view.

Image

Figure 9.10 FormLogonWebApp start page

Clicking on a link starts the process. Because the servlet being accessed is protected, a redirect to the identified login page is performed for the user to log in. Within each servlet mapping is an additional security-role-ref mapping. This is another level of abstraction with which the developer himself can identify roles that are needed within his code. Instead of hard coding roles within the code, the developer can make up own his role alias—in this case, MySalesRep—to use in the code and determine which role the user is in. In this simple example all the roles are actually the same, but consider the possibility of multiple roles being required within the servlet or application, which would be the case in any non-trivial application

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


<display-name>FormLogonWebApp</display-name>


<servlet>
    <display-name>CustomerList</display-name>
    <servlet-name>CustomerList</servlet-name>
    <servlet-class>com.ibmpress.web.customer.CustomerList</servlet-class>
    <security-role-ref>
        <role-name>MySalesRep</role-name>
        <role-link>SalesRep</role-link>
    </security-role-ref>
</servlet>

The EmployeeList servlet is described in the same manner with the security-role-ref being defined so that the developer can code to a specific name without worrying about what the real role name might end up being. The servlet mapping and the welcome-file-list items just tell the web container how to access each servlet and what the default welcome page will be.

<servlet>
       <display-name>EmployeeList</display-name>
       <servlet-name>EmployeeList</servlet-name>
       <servlet-class>com.ibmpress.web.employee.EmployeeList</servlet-class>
       <security-role-ref>
              <role-name>MyHRManager</role-name>
              <role-link>HRManager</role-link>
       </security-role-ref>
</servlet>
<servlet-mapping>
       <servlet-name>CustomerList</servlet-name>
       <url-pattern>/CustomerList</url-pattern>
</servlet-mapping>
<servlet-mapping>
       <servlet-name>EmployeeList</servlet-name>
       <url-pattern>/EmployeeList</url-pattern>
</servlet-mapping>
<welcome-file-list>
       <welcome-file>index.html</welcome-file>
</welcome-file-list>

The security–role identifies the actual roles that need to be mapped within the web container. These are the same roles that are linked within the servlet security-role-ref section.

<security-role>
        <role-name>HRManager</role-name>
</security-role>
<security-role>
        <role-name>SalesRep</role-name>
</security-role>

The web container will provide the capability to map user groups or sets of users to these roles within the administration console. Figure 9.11 shows an example of this mapping in the WebSphere Administration Console.

Image

Figure 9.11 Security role to user group mapping

Of interest to note is that you can set several default settings, such as Everyone or All Authenticated, for each role.

I have added an error JSP for completeness to the application. This is different from the LogonError.jsp, which is at the bottom of the xml file. The LogonError.jsp triggers if a problem occurs logging into the application, such as if there is an incorrect username or password. The error-page triggers after a successful login when the user is not authorized to view the page.

<error-page>
        <error-code>403</error-code>
        <location>/403Error.jsp</location>
</error-page>

This error is a common occurrence in many applications and I add it here to ensure that you can follow the security path through the application. With the default error page too much uncertainty exists as to whether the problem was supposed to occur or whether a bug exists in the application. With a custom error, as shown in Figure 9.12, you know exactly which error occurred within the application.

Everything in the web.xml up to now has been necessary, but has really been items that work behind the scenes. Actually securing resources within the application is performed within the security-constraint section of the file. This section contains two parts: the web-resource-collection, which identifies what resources need to be secured, and the auth-constraint section, which identifies which role has access to those resources.

Image

Figure 9.12 403 Error-Not Authorized

In this section I have created a constraint for each servlet in the application and set a different role for each one. This allows us to fully test the capability without too much effort. In the web-resource-collection are several parameters, which allow you to set different constraints on different aspects of the application. In this example I have only constrained the GET and POST methods of each servlet, but other options are available. For most applications finer grained control would probably be necessary.

<security-constraint>


        <display-name>CustomerList</display-name>


        <web-resource-collection>
                <web-resource-name>CustomerList</web-resource-name>
                <url-pattern>/CustomerList</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
        </web-resource-collection>


        <auth-constraint>
                <description>SalesRep</description>
                <role-name>SalesRep</role-name>
        </auth-constraint>


</security-constraint>


<security-constraint>


        <display-name>EmployeeList</display-name>


        <web-resource-collection>
                <web-resource-name>EmployeeList</web-resource-name>
                <url-pattern>/EmployeeList</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
        </web-resource-collection>


        <auth-constraint>
                <description>HRManager</description>
                <role-name>HRManager</role-name>
        </auth-constraint>


</security-constraint>

The final section of the web.xml is configuring the login method for the application. In this case we define that we want a form-based login and identify the login page and the error page in case there is some problem with the user logging in.

<login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
                <form-login-page>/login.jsp</form-login-page>
                <form-error-page>/loginError.jsp</form-error-page>
        </form-login-config>
</login-config>

On the surface this looks a little complex, but once you see how all the pieces fit together it makes some sense.

Running the Example

So what happens when you try to access a protected resource? As you might imagine the web container will see that you are trying to access a secure URL and redirect you to the login page, shown in Figure 9.13. This login page has been identified in the web.xml of the application.

Image

Figure 9.13 Redirect to login.jsp

On the login page you enter the username and password. If you are authorized to view the URL then you will get forwarded on to the CustomerList servlet shown in Figure 9.14. If you are not in the right role then you will see a result similar to Figure 9.12 (shown earlier).

Image

Figure 9.14 Successful login

The CustomerList servlet shows a few pieces of information that may be relevant to many applications. The first item is to get the username of the user who is logging in. In this case we get the name as an attribute within the session.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

PrintWriter out = response.getWriter();

String userName = (String)request.getSession().getAttribute("USER_ID");

if (userName != null) {
        out.println("Welcome to the CustomerList Servlet - " + userName);
} else {
        out.println("Welcome to CustomerList Servlet");
}

Second, a timestamp can often be used to log or determine when a user actually logged in. Again as an attribute on the session we can display this information.

String timeStamp = (String) request.getSession().getAttribute("LOGINTIME");
if (timeStamp != null) {
        out.println("Successful login on " + timeStamp);
} else {
        out.println("Successful login");
}

Finally, the isUserInRole() method can be used to determine whether a user has permissions to specific features within the application. In this case a Boolean holds the role value of a specific user and then displays whether that value is true or false. For this servlet the value has to be true because this role is required to access the servlet itself. Other applications may have a number of roles, any one of which could be true or false.

boolean salesrep = request.isUserInRole("MySalesRep");
out.println("(in role MySalesRep)You are a SalesRep: " + salesrep);

For completeness I have added a logout function within the page. This section displays a form that can trigger the ibm_security_logout method and then redirect to the logout.jsp page.

out.println("<form method=‘POST' action=‘ibm_security_logout'>");
out.println("<input type=‘submit' name=‘Submit' value=‘Log Out'>");
out.println("<input type=‘hidden' name=‘logoutExitPage' value=‘/logout.jsp'>");
out.println("</form>");


}

Interestingly enough we are not quite finished. You may have asked yourself the question about the values we got from the session for userid, and the login timestamp. Where do these values come from and are there additional values we can use within our application?

Adding a Filter to the Login Process

The specification allows for a filter to be injected into the login process so that you can do some pre- and post-processing of the logon event. By itself j_security_check does not provide a lot of information. The spec is pretty silent on implementation so it is left to the implementation to determine what features are available. The filter allows us to wrap the login process and give the application the additional information that it requires.

Adding the filter to the application is done by inserting a filter tag into the web.xml. This provides a filter class and the filter-mapping so that container knows what URL needs to be filtered. For the login process we need to put the filter on the j_security_check process.

<filter>
<description>Login Filter to provide additional Login Info</description>
<display-name>LoginFilter</display-name>
<filter-name>LoginFilter</filter-name>
<filter-class>com.ibmpress.web.login.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/j_security_check</url-pattern>
</filter-mapping>

A servlet filter consists of several parts based on its lifecycle. The three components to the lifecycle are init(), doFilter(), and destroy(). The init() and destroy() methods are pretty generic, but the doFilter() method provides the ability to manage data both before and after the login is performed. Within the doFilter() the first part of the method casts the ServletRequest and ServletResponse to an HTTPServletRequest and HTTPServletResponse for use within the code.

public void doFilter(
   ServletRequest req,
   ServletResponse resp,
   FilterChain chain)
   throws ServletException, IOException {

   HttpServletRequest hreq = (HttpServletRequest)req;
   HttpServletResponse hres= (HttpServletResponse)resp;

In the pre-login section we can extract the username and password from the request and place them on the session for future use.

    // pre login action
    // get username
    String username = hreq.getParameter("j_username");
    hreq.getSession().setAttribute("USER_ID", username);

After the pre-login section we pass control back to the web container to perform the login. This is the common way of working with servlet filters and allows filters to be chained together to perform many actions.

chain.doFilter(req, resp);

The post-login process creates a timestamp for the login and again places this value on the session. We now have the username and the time he logged in available on the session for this web application.

    // post login action
    // log the time stamp for login
    String timeStamp = null;
    Locale locale = req.getLocale();
    DateFormat df= DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.FULL, locale);
    timeStamp = df.format(new Date());
    hreq.getSession().setAttribute("LOGINTIME", timeStamp);
}

Attaching a filter opens up the possibilities for pre- and post-login processing (say that three times fast) and provides the application with a flexible and secure approach to managing access to its resources.

Architecting for Security

This chapter has covered a couple of cool security topics, but the higher goal is to help you figure out how to combine security into your architecture, especially in regards to a layered and likely distributed architecture described throughout this book. Maintaining a security context across a distributed environment can be a challenge. Many options are available to help with this challenge such as

•   WebSphere LTPA Single Sign-on

•   Principle/Credential Mapping with JAAS

•   Secure Association Service (SAS) used for backward compatibility for EJB authentication

•   Common Secure Interoperabilty Version 2 (CSIv2 ): Object Management Group standard for EJB authentication

•   Java 2 Security

WebSphere Single Sign-on

As distributed applications continue to grow several options are available that allow for security information to flow between distributed tiers within the infrastructure. Lightweight Third Party Authentication (LTPA) is a protocol that is designed for distributed as well as clustered application server environments. LTPA allows servers to securely communicate by sharing a secure token that can be encrypted and signed to identify an authenticated user. Figure 9.15 illustrates the flow for LTPA tokens in a single sign-on scenario.

Image

Figure 9.15 LTPA single sign-on

This feature allows a user to authenticate only once within the environment and be provided access to other applications within the domain. LTPA is highly secure; however, it is not an open standard, which means that LTAP tokens cannot be shared between other applications. WAS single sign-on is a little limiting in that LTPA tokens can only be shared with other WAS servers and Domino servers. For enterprise single sign-on, look to the Tivoli brand and Tivoli Access Manager series of products.

WebSphere Authorization

In a multi-layered application passing user credentials between layers is often necessary to ensure that the user, who authenticated at the front end of the application, has the necessary authorization to perform the requested function in the back end. Web applications and EJBs authenticate a client request in different ways, but the credentials are shared across the two. This means that when a user authenticates via the web app, those credentials are made available to EJB calls within the same application server. Figure 9.16 shows the authentication options available within WAS.

Image

Figure 9.16 WebSphere authentication

Identifying the user role within the application can be performed using several available methods:

•   EJB can use the getCallerPrincipal() and isCallerinRole() method to determine the user role.

•   Servlets can use the getRemoteUser(), isUserInRole(), and getUserPrincipal() to identify the same information.

You may have noticed in Figure 9.11 that two special roles or subjects were available for role/user mapping: AllAuthenticatedUsers and Everyone. These represent special sets of users that would probably not be identified within the user registry.

Revisiting the OrderWebServlet

Chapter 3 outlines an EJB3 application and a separate web app as the client, as shown in Figure 9.17. We can revisit this application with some security applied. The same approach is used for applying security on the web application as the previous example. However, a different approach is used for applying security to the EJB layer.

Image

Figure 9.17 Distributed example

Using EJB3 annotations we can apply declarative security and declare roles right within the application code. In the following sample code I have declared a role of manager and then applied that role to both of the methods with the EJB.

@DeclareRoles(“manager”)

public class OrdersFacadeImpl implements OrdersFacade,
OrdersFacadeRemote {

         OrdersManager orderManager = new OrdersManager();

         @RolesAllowed (“manager”)
         public List<Orders> getOrders() {
         …
         }

         @RolesAllowed (“manager”)
         public Orders findOrdersByOrdernumber(short ordernumber) {
         …
         }

Once security is applied to the EJB application the methods will require the proper access rights to access the application. Running the application again the application will fail because no groups are mapped to the manager role.

4/8/08 20:38:24:906 EDT] 00000022 SecurityColla A SECJ0053E:
Authorization failed for defaultWIMFileBasedRealm/User1 while invoking
(Bean)<null> findOrdersByOrdernumber(short):1 securityName: defaultWIMFileBasedRealm/User1;accessID: user:defaultWIMFileBasedRealm/uid=User1,
o=defaultWIMFileBasedRealm is
not granted any of the required roles: manager


[4/8/08 20:38:24:953 EDT] 00000022 ServletWrappe E SRVE0068E: Uncaught exception thrown in one of the service methods of the servlet: OrderWebServlet. Exception thrown : javax.ejb.EJBAccessException:
SECJ0053E: Authorization failed for defaultWIMFileBasedRealm/User1 while invoking (Bean)null findOrdersByOrdernumber(short):1 securityName: defaultWIMFileBasedRealm/User1;accessID: user:defaultWIMFileBasedRealm/uid=User1,
o=defaultWIMFileBasedRealm is not granted any of the required roles: manager

The final step in this process would be to map one or more user groups to the manager role. As of this writing the available tooling is not quite ready to illustrate that portion of the exercise.

Conclusion

Most architects will understand that as with most of the chapters in this book we have only just scratched the surface of what security options are available, and what your responsibilities are in this area. For example Java 2 security has not been mentioned; however, it may be a key component of your strategy if you need that granular of a security model. Java 2 security can be a big step for an organization, especially within a shared environment. You can learn more about Java 2 security and how it is implemented in the WebSphere Application Server InfoCenter at http://publib.boulder.ibm.com/infocenter/wasinfo/ v6r1/topic/com.ibm.websphere.nd.multiplatform.doc/info/ae/ae/csec_rsecmgr2.html? resultof=%22%4a%61%76%61%22%20%22%6a%61%76%61%22%20%22%32%22%20%22%53%65%63%75%72%69%74%79%22%20%22%73%65%63%75%72%22%20.

I should note that much of the form login example was adapted from the technology samples that come with WAS. I simplified the stock example a bit and added some role mappings to show how everything can work together. The technology samples are a good place to start looking when you are not sure how to do something, or do not know what features even exist within the server.

Image

Links to developerWorks Articles

A9.1 Application Architecture Security, Thomas Myer, http://www.ibm.com/developerworks/library/ar-apparch7/

A9.2 Seven lesser known system attacks and how to defeat them, Sean-Phillip Oriyano, http://www.ibm.com/developerworks/library/ar-sevatt/

A9.3 WebSphere Application Server V6 advanced security hardening, Keys Botzum, http://www.ibm.com/developerworks/library/ar-sevatt/

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.214.37