ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Java vs. .NET Security, Part 4
Pages: 1, 2, 3, 4, 5

User Access Security: Extended

In addition to the basic facilities for user access checks, extension packages on both platforms define their own mechanisms.

ASP.NET provides security checks, which work on the top of regular CLR security facilities:

  • FileAuthorizationModule: Performs ACL checks on accessed .aspx and .asmx files. It is active when Windows authentication is enabled, and is used to determine whether the user passes Windows ACL checks.

  • HTTP handlers: There are several of these specified in machine.config to prevent disclosure of certain types of files. Note that this mechanism works separately from the IIS-defined one, and only for the file extensions registered to ASP.NET, so separate IIS configuration is needed to ensure full protection.

    <httpHandlers>
      <add verb="*" path="*.vjsproj" 
             type="System.Web.HttpForbiddenHandler"/>
      <add verb="*" path="*.java" 
    
             type="System.Web.HttpForbiddenHandler"/>
      ...
      <add verb="*" path="*" 
      type="System.Web.HttpMethodNotAllowedHandler"/>
    </httpHandlers>
  • URLAuthorizationModule: Performs URL authorization by providing declarative hierarchical mapping of users and roles to the URI namespace. This mode and allows for positive and negative assertions on the protected resources, and accepts the wildcards * for all users and ? for anonymous users. There is a global configuration file, and each subdirectory may have its own version of it, overwriting some attributes. The hierarchy is parsed starting from the lowest level, and the first match wins. This is certainly the quickest way to enable access control, but not necessarily the best, because it scales poorly and is not easily manageable, especially for multi-server applications.

    <authorization>
      <allow users="Don, MyDomain\Don" roles="Admin"
                    verbs="GET, POST">
      <deny users="?" roles="Guest" >
    </authorization>

Java servlets and JSPs use role-based access control checks, which can be specified programmatically or declaratively, similar to ASP.NET. The mapping between authenticated users and security roles is not specified; it happens in a vendor-specific way. However, the servlet specification does standardize ACL declarations by security roles in the web.xml deployment descriptor, which can protect web resources defined as HTTP methods applied to URL-patterns. Also, the transport-guarantee element is considered during requests evaluation. A side effect of this approach is that the resulting declarative access control mechanism is rather coarse, on the file/operation level:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Restricted Servlets
       </web-resource-name>
    <url-pattern>/myserver/AccountingServlets/*
       </url-pattern>
    <url-pattern>/myserver/FinanceServlets/*
       </url-pattern>
    <http-method>POST</http-method >
    <http-method>GET</http-method >
  </web-resource-collection>
  <auth-constraint>
    <role-name>owner</role-name>
  </auth-constraint>
  <user-data-constraint>
    <transport-guarantee>INTEGRAL
      </transport-guarantee>
  </user-data-constraint>
</security-constraint>

Violation of the auth constraint will result in either the HTTP 401 (if unauthenticated) or HTTP 403 (if authenticated, but ACL-rejected) status code being returned to the caller. For cases of anonymous web users, the web application's deployment descriptor may contain a <run-as> element, which will specify the identity that will be used to process the request. If it is specified, the servlet container is required to propagate this security identity in calls to the EJB layer, whether in the same or in a different J2EE application, as was explained in the Identities section.

Principal checks may be performed imperatively, using one of the methods exposed by HttpServletRequest: getUserPrincipal, getRemoteUser, or isUserInRole. They can be used to provide finer-grained checks than declarative security allows for:

public void doGet(HttpServletRequest request, 
         HttpServletResponse response) {
  java.security.Principal principal = 
           request.getUserPrincipal();
  String user = request.getRemoteUser();
  if (user != null) {
    //have an authenticated user, check his name
  } 

  if (request.isUserInRole("owner")) {
    //owner of the account
  }
}

EJB role-based security is similar to that of servlets, and can be declarative or programmatic. However, the declarative variant is finer-grained, as it allows access control up to the methods level. Mapping of principals to roles is vendor-specific, but the EJB specification dictates role-based ACL format in the bean deployment descriptor, with * as a wildcard for all permissions:

<assembly-descriptor>
  <security-role>
    <description>Role description</description>
    <role-name>UserRole</role-name>
  </security-role>
</assembly-descriptor>

<method-permission>
  <role-name>UserRole</role-name>
  <method>
    <ejb-name>UserAccess</ejb-name>
    <method-name>*</method-name>
  </method>
  <method>
    <ejb-name>OwnerAccess</ejb-name>
    <method-name>getUserInfo</method-name>
  </method>
</method-permission>

Using the <unchecked> element in the bean's descriptor will bypass any authorization, even if the <role-name> element is also specified.

Some methods may even be excluded from being called at deployment time by specifying an exclude list. This list provides a directive from the application assembler to the deployer that these methods should be configured to deny any access:

<exclude-list>
  <method>
    <ejb-name>SomeBean</ejb-name>
    <method-name>problematicMethod</method-name>
  </method>
</exclude-list>

Alternatively, the principal's attributes can be accessed from the bean's code, using methods exposed by the EJBContext class. Note that those methods may be invoked only in the EJB business methods with security context present -- otherwise, a java.land.IllegalStateException will be thrown. Also, both the getCallerPrincipal and isCallerInRole methods from EJBContext always operate on the caller identity, even if the <run-as> attribute was specified.

public class UserAccessBean 
                 implements SessionBean {
  EJBContext beanContext;

  public void getUserInfo() {
    java.security.Principal principal = 
            beanContext.getCallerPrincipal();
    if (beanContext.isCallerInRole("UserRole")) {
      //authenticated user 
    }
  }
}

Note: For extended access checks, both systems provide an adequate level of declarative support.

Conclusions

This article addressed the user authentication and authorization features of the Java and .NET platforms. .NET suffers from tight integration with IIS, without which it is not really capable of performing authentication. In terms of access control, it does provide a convenient mechanism that meshes nicely with its CAS features. Java, in addition to the standard authentication types, offers the powerful JAAS mechanism as its primary vehicle for adding authentication and Principal-based authorization to Java applications, which adds a lot of flexibility to the design choices.

Overall, .NET and Java both earned pretty high marks on the security comparison, which should not be too surprising, considering the long history of Java in the enterprise and the amount of effort that Microsoft is putting into making .NET a premier Windows development platform. Traditionally (and .NET is not an exception), Microsoft products have done best in the closed, homogeneous environment of all-Windows networks, while enterprise Java performs quite well in heterogeneous environments. If we consider an all-Microsoft network, it allows system integration and utilization of .NET's security features to their fullest potential. In case of a mixed environment, Java's platform-independent security features may be more useful than those of .NET. Also, when issues like communication security and authentication across networks start coming into play, Java seems to be a good choice.

Demo Applications

Bibliography

Denis Piliptchouk is a senior technical member of BEA's AquaLogic Enterprise Security group, participates in OASIS WSS and WS-I BSP standards committees, and regularly contributes to industry publications.


Return to ONJava.com.