In this Spring Security Tutorial Series we will take a look how to use Spring Security with XML Namespace Configuration with Example of authentication and access-control using <http>, <intercept-url> namespaces. In my earlier article We have seen Spring Security Java Configuration Annotation Example of Authentication and access control using @Secured, @PreAuthorize and JSR-250 @RolesAllowed annotations. As we know that Spring Security is a very powerful and highly customizable authentication and access-control framework.
XML Namespace configuration has been available since Spring Security 2.0. In Spring Framework, A namespace element is nothing but it is a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax. It actually hides the underlying bean definition complexity from the user. For using the spring security namespace in your application context, you need to have the spring-security-config jar on your classpath. And finally you need to add the schema declaration to your application context file as below:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:>Popular Tutorialsweb.xml Configuration (Setup DelegatingFilterProxy and springSecurityFilterChain)
FilterChainProxy add a single entry to web.xml and deal entirely with the application context file for managing our web security beans. It is wired using a DelegatingFilterProxy, just like in the example above, but with the filter-name set to the bean name "springSecurityFilterChain". In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure bean created by the namespace to handle web security.Define the single proxy filter
– springSecurityFilterChain is a mandatory name -Refers to an existing Spring bean with same name<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>17-Spring-Security-XML-Namespace-Config</display-name> <servlet> <servlet-name>doj</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>doj</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Spring Security Namespace Configuration in the Application Context fileOnce you’ve added DelegatingFilterProxy and springSecurityFilterChain to your web.xml, you’re ready to start editing your application context file. Web security services are configured using the <http> element.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:> http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.doj.app.controller"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="suffix" value=".jsp"/> <property name="prefix" value="/WEB-INF/view/"/> </bean> <security:http> <security:intercept-url access="hasRole('USER')" pattern="/**" /> <security:form-login/> <security:logout/> </security:http> <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="admin" password="adminpassword" authorities="ROLE_USER, ROLE_ADMIN" /> <security:user name="user" password="password" authorities="ROLE_USER" /> </security:user-service> </security:authentication-provider> </security:authentication-manager> </beans>As according to the above application context file, we want all URLs within our application to be secured, requiring the role ROLE_USER to access them, we want to log in to the application using a form with username and password, and that we want a logout URL registered which will allow us to log out of the application. The configuration above defines two users, their passwords and their roles within the application.
Thus far Spring Security generates login form automatically, based on the features that are enabled and using standard values for the URL which processes the submitted login, the default target URL the user will be sent to after logging in and so on.
<security:http pattern="/login" > From Spring Security 3.1 it is now possible to use multiple http elements to define separate security filter chain configurations for different request patterns. It is also possible to have all requests matching a particular pattern bypass the security filter chain completely, by defining a separate http element for the pattern like this /login, "/resources/", "/scripts/", "/css/" etc.Handling Logouts
When using the <security:logout/>, logout capabilities are automatically applied. The default is that accessing the URL /logout will log the user out by:
<security:logout invalidate-session="true" delete-cookies="AppCookies" logout-url="/logout" logout-success-url="/home"/>
There are three built in options:
<security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="admin" password="adminpassword" authorities="ROLE_USER, ROLE_ADMIN" /> <security:user name="user" password="password" authorities="ROLE_USER" /> </security:user-service> </security:authentication-provider> </security:authentication-manager>
<authentication-manager> <authentication-provider> <jdbc-user-service data-source-ref="dataSource"/> </authentication-provider> </authentication-manager>
Where "dataSource" is the name of a DataSource bean in the application context, pointing at a database containing the standard Spring Security user data tables.
You can also customize how passwords are encoded by exposing a PasswordEncoder as a bean. We can encode passwords using a hash – sha, md5, bcrypt etc.
<security:http pattern="/login" ><bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> <security:authentication-manager> <security:authentication-provider> <security:password-encoder ref="bcryptEncoder"/> <security:user-service> <security:user name="admin" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f" authorities="ROLE_USER, ROLE_ADMIN" /> <security:user name="user" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" authorities="ROLE_USER" /> </security:user-service> </security:authentication-provider> </security:authentication-manager>
From Spring version 2.0 Spring Security provides support to adding security to your service layer methods. Spring Security uses AOP for security at the method level.
– annotations based on Spring annotations or JSR-250 annotations
– Java configuration to activate detection of annotations
- From 3.0 you can also make use of new expression-based annotations.
Typically secure your services
– Do not access repositories directly, bypasses security (and transactions)
<global-method-security>- This element is used to enable annotation-based security in your application. The following declaration would enable support for Spring Security’s @Secured:
<global-method-security secured-annotations="enabled" />
import org.springframework.security.annotation.Secured; public class ItemManagerService { @Secured("IS_AUTHENTICATED_FULLY") public Item findItem(long itemNumber) { ... } }
We can also use
Note: Spring 2.0 syntax, so not limited to roles. SpEL not supported.
Support for JSR-250 annotations can be enabled using.
<global-method-security jsr250-annotations="enabled" />
import javax.annotation.security.RolesAllowed; public class ItemManagerService { @RolesAllowed({"ROLE_MEMBER", "ROLE_USER"}) public Item findItem(long itemNumber) { ... } }
Note: Only supports role-based security – hence the name
To use the new expression-based syntax, you would use
<global-method-security pre-post-annotations="enabled" />
public interface ItemManagerService { @PreAuthorize("isAnonymous()") public Item findItem(Long itemNumber); @PreAuthorize("isAnonymous()") public Item[] findItems(); @PreAuthorize("hasAuthority('ROLE_USER')") public Item post(Item item); }
The use of protect-pointcut is particularly powerful, as it allows you to apply security to many beans with only a simple declaration. Consider the following example:
<global-method-security> <protect-pointcut expression="execution(* com.doj.app.*Service.*(..))" access="ROLE_USER"/> </global-method-security>
This will protect all methods on beans declared in the application context whose classes are in the com.doj.app package and whose class names end in "Service". Only users with the ROLE_USER role will be able to invoke these methods.
Spring Security Related Posts
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…