In this article by Nanda Nachimuthu, author of the book Spring Security Essentials, we will see that when talking about enterprise security; three major areas of security, authentication, authorization, and access control list (ACL) play a major role. Spring Framework 4.0.3 has a seven-layered architecture that includes core container, context, Aspect Oriented Programming (AOP), Data Access Object (DAO), Object-relational mapping (ORM), web and Model-View-Controller (MVC). In order to provide security features to all these layers, we have Spring Security 3.2.3 module that will provide security facilities such as user authentication, authorization, role-based authorization, database configuration, and password encryption.
(For more resources related to this topic, see here.)
In general, the Spring developers may focus on the seven layers to develop the web applications and most of them will not be able to master the security mechanisms that are involved in different layers with different implementations as they may have to call the abstract programs in which the security implementations may be in built.
Spring 3.2.3 supports various authentication approaches for different industry standard connectivity for Java EE-based enterprise applications. Many people use Spring Security in the layers of Java EE's Servlet Specification and Enterprise Java Beans (EJB) specification that will limit the usage of proper Spring Security implementation. Due to this, many enterprise security scenarios are left unattended. Authentication is the process of creating a principal in the enterprise system for which the user needs to provide their credentials. The role-based access privileges will be decided on a predefined role authorizer system from where the core system will read the access rights for the given principal. The advanced techniques of Spring Security mechanisms are as follows.
- Custom user realms
- Custom authorization constraints
- Method-based authorization
- Instance-based authorization
- Building a security layer for RESTful web services
The following modules of Spring 3.2.3 supports implementation of the enterprise security:
- Spring Security Core
- Spring Security remoting
- Spring Security web
- Spring Security config
- Spring Security LDAP
- Spring Security ACL
- Spring Security CAS
- Spring Security OpenID
Also, we are going to cover specific techniques such as JavaServer Faces (JSF) 2.0, Wicket, and Java Authentication and Authorization Service (JAAS). The following are the new security features that are provided in Spring 4.0 that we may talk a little later:
- WebSocket support
- Test support
- Spring Data Integration
- Cross-Site Request Forgery (CSRF) token argument resolver
- More secure defaults
Most of these authentication levels are from many third parties or developed by relevant standard bodies, such as Internet Engineering Task Force (IETF). Also, Spring Security has its own authentication features that will be useful for the purpose of establishing connections securely with third party request headers, protocols, and single sign on systems.
Spring custom user realms
Custom security realms facilitates using an existing data store, such as a directory server or a database, when authenticating and authorizing users to enterprise applications that are deployed in a standard application servers, such as WebSphere, JBoss, and so on. We may have to provide the attribute details to the server in order to create the user realms, such as name, realm class name, configuration data, and password. We can create a custom realm by providing a custom JAAS login module class and a custom realm class. However, when we are using client-side JAAS login modules, this may not be suitable for use with the enterprise server.
There can be two different realms that are catering to two different URL patterns. We can use the same authentication logic for both realms. The standard Spring Security mechanism will invoke j_spring_security_check automatically when a login form is called and we can define our own URL, which is to be intercepted. This approach is called browser-based client security realm. If the user is not provided with a username and password and if the principal is not created to access this URL, then the user will be redirected to the login page by the Spring Security checker.
Spring custom authorization constraints
There are many types of security constraints. This consists of Web Resource Collections, such as URL patterns, HTTP methods, and authorization constraints by providing role names, user data constraints such as the web request is passed over an authenticated transport. A security constraint is used to define the access privileges to a collection of resources using their URL mapping. The security token will be given from an HTTPS request, then it gets validated, and will be given back to enterprise application server. There may be possibilities that the security token is not returning any valid roles for the authorization.
In such scenario, we may have to set the security authorization constraints in a secured way in the web.xml file. The web resources can have unchecked access, checked access, and no access. We can omit the authorization constraints so that any web resources can access the resource. We can specify the role name for the authorization constraint so that only these roles can access the web resource. Otherwise, we can exclude a set of web resources from accessing any request by specifying no roles for these resources. We can also exclude particular URLs from accessing the specific secured web resources.
Spring method-based authorization
Method security is a bit more complicated than the simple allow or deny rule. Custom methods can be provided with specific security settings. In Spring, we can achieve this by providing the proper annotations for the methods to be secured. There are four annotations that support expression attributes to allow pre- invocation and post-invocation authorization checks and also to support filtering of the submitted collection arguments or return values. They are @PreAuthorize, @PreFilter, @PostAuthorize, and @PostFilter. If you want to create a custom secured method called customCheckUser(), then you can annotate the method with the @PreAuthorize tag for doing a pre-security check before execution.
While the other security methods are focusing on servlets and controllers, security method-based authorization is dealing with the service layer components particularly. We can control various services to be accessed by specific principals. For example, admin principal can only access the database credential layer or the logging layer can be accessed by all principals. The global method security tag or the @EnableGlobalMethodSecurity annotation will help the developers in setting up the method-level security.
Spring instance-based authorization
In class level, we can check when we are creating an instance for a particular request whether the intended principal is authorized to invoke the particular instance or not. This can be achieved by providing annotations before instantiating the object to check the authenticity. This instance-based security is important while handling the non-application server related code or any code related to business logic that needs to be closely monitored to prevent non-privileged access.
Here, the approach is to define the information clearly so that the domain object-based security restrictions can be applied accurately. The actor who is performing the use case action, the domain actor created internally to perform the action, and the intended action is the information that we need to define clearly in order to achieve the instance-based authorization. Here comes the usage of ACL and Access Control Entries (ACE). The advantage of using Spring ACL and ACE here is that Spring has an internal mechanism in order to manage the ACE volume by implementing ACE inheritance mechanism so that when number of domain objects grows, the ACE also will become manageable.
Apart from the previously mentioned techniques, Spring provides options to build a security layer for RESTful and SOAP web services and we can create security layers for JSF 2.0 and Wicket. Let's take a quick look of these four techniques now.
Spring Security with SOAP web service
Spring Web Services (Spring-WS) packages focus mainly on the creation of document-driven web services, where the data communication between web services is done through XML envelops and web services can be accessed from any other technology application servers. The features supported by Spring-WS are the powerful XML mappings, support for various XML APIs, flexible XML Marshalling, WS-Security support, and so on. The WS-Security comprises of three areas such as authentication, digital signatures, and encryption/decryption.
The security flow in Spring-WS will be as follows:
- The system will generate a security token for the valid principal using a separate web service method.
- If the user wants to access other web services, he should pass this token along with the payload as a security key and the web services will validate this token for authenticity, and then allow the users to access the resources.
- If the token has expired or invalid user should go through the authentication web service once again.
This entire mechanism is called as Message Signing.
Spring Security with RESTful web service
To achieve Representational State Transfer (REST) services calls with basic security authentication, we may have to depend on the libraries provided by the Spring framework such as core, config, and web. Also, we need to make some entries in Spring application context files.
In real time scenarios, we may have to get the credentials from Lightweight Directory Access Protocol (LDAP), database, and so on.
Spring Security with JSF 2.0
Coming to the JSF and Spring Security integration, Spring web flow provides a JSF integration that simplifies the handshake between JSF and Spring. Dedicated Spring Security Tag Libraries are available for JSF Security integration. To achieve this, springsecurity.taglib.xml needs to be updated with Facelets entries. These modifications must be reflected in web.xml as well. We can include the nested contents based on security conditions using authorize tags. At the time of JSF rendering, many Expression Language (EL)-based functions can be used.
Spring Security with Wicket
Apache Wicket is designed based on the component-oriented structure and less HTML file handling. Wicket-related security settings must be handled first by modifying the web.xml file for the corresponding filter mappings. As a Wicket programmer, you may have to be clear in understanding about the pull and push concepts and form processing life cycle of Apache Wicket framework. There are two unique issues to be handled from Wickets part, that is, Wicket does not manage the life cycle of its components and models and components of Wicket are often serialized, which may be an issue for Spring's dependency injection mechanism. The workaround for this will be some entries in the web and applicationContext XML files; however, this approach will still have its own pros and cons.
In this article, we have seen different techniques of Spring Security mechanisms, and how to build a security layer for RESTful and SOAP web services, and how we can create security layers for JSF 2.0 and Wicket.
Resources for Article:
- Introduction to Spring Web Application in No Time [article]
- Mailing with Spring Mail [article]
- Creating a Spring Application [article]