Spring Security
provides a very good security solution(s), handling authentication and authorization
at the web request level and at the method invocation level by using the
features of Dependency Injection (DI) & Aspect Oriented techniques.
Spring security
targets two areas viz. 1. Authentication
&
2. Authorization
1. Authentication: - is the assurance that the user is
the actual user he is claiming to be.
E.g. Particular user logs into the application
through his credentials means get authenticated himself.
Spring Supports following types of
Authentication :
a.
Http Basic Authentication
b.
Form Based Authentication
2. Authorization: - is the assurance that the user is
allowed to access only those resources that he is authorized to use.
E.g. Admin of the any website have access for
some parts/pages & normal user done have access to these pages.
For authorization spring targets following
areas,
a.
Authorizing web requests
b.
Authorizing whether methods can be
invoked
c.
Authorizing access to individual
domain objects
Following jar’s
need to be present in the class path of the project.
1. Core => spring-security-core.jar
2. Web
=> spring-security-web.jar
3. Config
=> spring-security-config.jar
Namespace Configuration :-
Spring Security
comes with a security-specific namespace which simplifies security
configuration in Spring. This new namespace, along with some default behavior,
reduces a typical security configuration from over 100 lines of XML to a dozen
or so. The namespace configuration of the Spring provides a shortcut that hides
much of complexity of the framework.
E.g.
<beans
xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:
…..>…..</security:…>
</beans>
For web security in Spring, we must set up the
servlet filters that provide the various security features.
Proxying servlet
filters :-
<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>
In above code snippet DelegatingFilterProxy deligates the
control to a filter implementation which is defined as bean named springSecurityFilterChain. This bean is an
infrastructural bean to handle namespace
configurations. Once this configuration is done, all the incoming requests
enter the spring framework for security check. This special filter, by
itself will not do much, it deligates to an implementation of
javax.servlet.Filter which is registered as <bean> in spring application
context.
It is not possible to inject beans
into the servlet filters registered into the web.xml. But by using DelegatingFilterProxy,
we can we can configure the actual filters.
<filter-name> given to the DelegatingFilterProxy is very
significant & useful. This name is used to look up the filter bean from the
Spring application context. Spring Security will automatically create a filter bean whose ID is
springSecurityFilterChain, so that’s the name, given to DelegatingFilterProxy
in web.xml.
springSecurityFilterChain bean itself is another special filter known
as FilterChainProxy. It’s a single
filter which chains one or more filters. Spring Security will automatically
create those beans for us when we configure the <http> element.
Security Configuration :-
We can define security configuration
file as applicationContext-security.xml &
this file need to be loaded in web.xml. This
is done by ContextLoadListner.
Following snippet needs to be added in
web.xml before security filter definition.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext-security.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
applicationContext-security.xml
Whenever
namespace configuration is used, spring-config.jar
needs to be in class path. The first line in this file should be like,
<beans
xmlns="http://www.springframework.org/schema/security"
xmlns:bean="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
...
</beans>
The minimal namespace configuration
like:-
Following only three lines of XML
configures spring security to intercept all requests for all URL’s and restrict
access to only authenticated users who have
“ROLE_USER” role. This <http> element automatically set up FilterChainProxy & all the filter
beans in the chain shown in following diagram.
<http auto-config=”true”>
<intercept-url pattern=”/**” access=”ROLE_USER”
/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="testadmin"
password="testadminpassword"
authorities="ROLE_USER,
ROLE_ADMIN" />
<user name="testuser" password="testuserpassword"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
The attribute auto-config=”true" defines three elements
<form-login/>, <http-basic/> and <logout>.The default
configuration always chooses http-basic authentication model. If the model
needs to be changed to the form-login model, then the following configuration
is needed.
<http auto-config=”true”>
<intercept-url
pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url
pattern="/**" access="ROLE_USER" />
<form-login login-page=”/login.jsp”/>
</http>
This above
configuration is done to enable form-login authentication model where the login
page is login.jsp.
Note that in the intercept tag, pattern for login.jsp is given and access rule is defined as IS_AUTHENTICATED_ANONYMOUSLY.
That means login.jsp
is not checked for security, which makes sense as login.jsp is the
starting point from where the user is authenticated.
The tag <authentication-manager> processes the
authentication information; <authentication-provider>
defines the credential information and the roles given to each user
(authentication information).
Spring Security framework is a chain of
filters, with each filter having certain responsibility.
In following section the namespace
configuration to bean configuration to understand the flow and responsibility
of each filter.
The <http>
block in namespace configuration invokes the chain of filters. DelegatingFilterProxy that is
defined in web.xml
invokes the FilterChainProxy
class which in turn invokes the chain of filters defined for each
URL pattern.
The chain of filters that FilterChainProxy calls are shown
below:
To
override the default behavior of login page, need to configure
<form-login> element,
<http auto-config="true"
use-expressions="false">
<form-login
login-processing-url="/static/j_spring_security_check"
login-page="/login"
authentication-failure-url="/login?login_error=t"/>
</http>
login attribute
specifies a new context-relative URL for the login page & it will reside at
/login which is ultimately handled by a Spring MVC controller.
If
authentication fails, the authentication-failure-url
attribute is set to send the user back to the same login page.
Intercepting
requests : -
<intercept-url> Element is the
first line of defense in request level security. Its pattern attribute is given a URL pattern that will be matched
against incoming requests. If any requests match the pattern, then that <intercept-url>’s security rules
will be applied.
<intercept-url
pattern="/**" access="ROLE_USER" />
/**
=> indicating that we want all requests, regardless of the URL, to require
ROLE_USER access
For
area for admin & restricted to others’ in this case following snippet need
to put before previous <intercept_url>
<intercept-url
pattern="/admin/**" access="ROLE_ADMIN" />
This
will restricts the access to the /admin of site’s hierarchy to users’ with
ROLE_ADMIN authority. We can use many <intercept-url> entries as we
require securing various paths of application.
<intercept-url>
rules are are applied top to bottom.
SECURING WITH
SPRING EXPRESSIONS: -
Spring
Expression Language (SpEL) as an advanced technique for wiring bean properties.
To
enable it, we must set the use-expressions attribute of <http> to true:
<http
auto-config="true" use-expressions="true">
……....
</http>
Use
of SpEL expression:-
<intercept-url
pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
Securing
view-level elements :-
To
support security in the view layer, Spring Security comes with a JSP tag
library. This tag library is small and includes only three tags,
<security:accesscontrollist> - Allows the
body of the tag to be rendered if the currently authenticated user has one of
the stipulated permissions in the specified domain object
<security:authentication> - Accesses
properties of the current user’s authentication object
<security:authorize> - Allows the
body of the tag to be rendered if a specified security constraint has been met
To
use the JSP tag library, we’ll need to declare it in the JSP file,
<%@
taglib prefix="security" uri="http://www.springframework.org/security/tags"
%>
Accessing
authentication details :-
This
tag library provide convenient access to user’s authentication information,
e.g.
Welcome XYZ ! …. At the header of application.
Welcome <security:authentication
property="principal.username" />!