Shibboleth Integrated Spring Security ... - SourceSup

oklahomaflockSecurity

Nov 3, 2013 (4 years and 6 days ago)

1,628 views

Shibboleth Integrated Spring Security
Implementation Guide

This document describes how to integrate Shibboleth

Service Provider (SP)

enabled SSO
solution with

Spring Security Framework. Since security requirements for a web application are
vary, the purpose of this do
cument is only to show a generic

integration solution. Readers are
encouraged to customize both Shibboleth configuration and Spring security to su
ite their
applications. It

should be used with another document named “Shibboleth Service Provider 2.3
configuration Guide” to develop web security solutions based on Shibboleth.

Besides, readers
should have some basic knowledge of both Spring and Spring S
ecurity Framework.

Prerequisites



Java SDK 1.5+



Spring Framework 3.0+



Spring Security Framework 3.0+



Shibboleth 2.3,
A
pache

2.2

and Tomcat

6.0+


How It All Fit Together

The Shibboleth operates inside the Apache web server and it places authentication and
attribute
information into the web application environment using environment variables or using customer
HTTP request headers. General speaking, there are two steps to start:

1.

Start a Shibboleth session.

2.

Deliver environment/header variables to the applicat
ions’ authentication and
authorization

point
.

Shibboleth can automatically establish a session

whenever an URL is accessed. This means that
any user accessing that resource must be authenticated by an Identify Provider. To always
require that a session e
xist,
ShibRequireSession On
Apache directive is
the Apache server
configuration file.


Shibboleth can also use lazy session initiation to establish a new session. In such a case,
application can request that a session be created on demand by redircting

a user to a local URL
bound to a <SessionInitiator>.


I
n this document, we use the first approach to establish a session. This means that a user will
always be challenged to enter
into
an authentication process in order to access any resources

from the web application
.


After successful authentication
, the application can expects certain attributes passed by web
server environment variables and HTTP headers. These attributes can be accessed in the
following ways:


Java Environment Access

r
eque
st.getAttribute(“Attribute Name”);


Java Header Access

r
equest.
getHeader
(“Attribute Name”);

A
pache Setup

Make sure requests for /Shibboleth.sso/* don’t get passed to Tomcat as these links are used for
Shibboleth handlers. The commands used are as follow:

LoadModule jk_module modules/mod_jk.so

JkMount /* ajp13

JkUnMount /Shibboleth.sso/* ajp13

JkUnMount /shibboleth ajp13

JkUnMount /shibboleth
-
sp/* ajp13

In Shibboleth 2, we need to turn on the Shibboleth Headers, because, by default, the Shibboleth
Service P
rovider only populates environment variables rather HTTP headers:

<Location />


AuthType shibboleth


r
equire shibboleth


ShibRequireSession On


ShibUseHeaders On

</Location>

Tomcat Setup

In the AJP connector configuration part of Tomcat server.xml, we need to add
tomcatAuthentication=”false” or the REMOTE_USER header will not be passed from Apache to
Tomcat.


<Connector port=
"8009"

enableLookups=
"
false
"

redirectPort=
"8443"

protocol=
"AJP/1
.3"


tomcatAuthentication=
"
false
"
/>

Configure Attributes

The S
hibboleth Service Provider

(SP)

translates attribute that it receives from the Identify
Providers. These attributes can be configured in
etc/shibboleth/
attribute
-
map.xml configuration
file.
It contains a series of mapping rules that translates attributes to a more convenient short
-
hand. These attributes then will be available through environment variable or header to the web
application. The following is an attribute mapping example:

<Attribu
te name=
"https://example.org/myAttributes/FavoriteFruit"

id=
"favFruit"
/>

The
Name

property

corresponds to the name defined in Identify Provider, generally a URI. The
Id property is the name which can be used in the web application to access the attribute.

You can use attribute
-
map.xml to define any attributes you want to use in the web application.

The Shibboleth Service Provider defines a unique identity which can be used as a primary key to
reference a user each time they visit the web application. The fo
llowing is the definition of the
primary key:


<Attribute name=
"urn:mace:dir:attribute
-
def:eduPersonTargetedID"

id=
"persistent
-
id"
>


<AttributeDecoder xsi:type=
"NameIDFromScopedAttributeDecoder"

formatter=
"$NameQualifier!$SPNameQualifier!$Name"

defaultQualifiers=
"
true
"
/>

</Attribute>

Spring Security Configuration

Spring
security has the build
-
in support for integrating with other SSO solutions.
Most of the
classes are defined in the
org.springframework.security.web.authentication.preauth

package.

So
the main task is to customize or implement the existing Spring related classes to suit Shibboleth
Service Provider.

Since Shibboleth Service Provider (SP) handles the authentication process, the
Spring Security

Framework

will expect the SP to provide a
n authenticated User Identifier

and
establish a related session for the user. In option, a following authorization process can be
created

as well.


The tasks are listed as follows:



Create a custom entry point



Create a pre authentication filter



Define a log
out handler



Create
a
n

authentication provider



Create

a

use
r

details service.



Create
a
n

authorization provider

The following is the example
of Spring Security configuration file

which is configured to use
classes created as mentioned in the above taskes
. It

also configures the basic Spring Security
metadata.

<http entry
-
point
-
ref="customEntryPoint" access
-
decision
-
manager
-
ref="affirmativeBased">


<custom
-
filter ref="preauthenticationFilter" position="PRE_AUTH_FILTER" />


<
logout invalidate
-
session="true" logout
-
success
-
url="http://localhost/Shibboleth.sso/Logout" logout
-
url="/logout"/>



<intercept
-
url pattern="/error.htm" access="IS_AUTHENTICATED_ANONYMOUSLY" />


<intercept
-
url pattern="/admin.htm" access="ROLE_ADMIN" />


<intercept
-
url pattern="/**" access="ROLE_USER" />

<
/http>



<authentication
-
manager alias="authenticationManager">


<authentication
-
provider ref="myAuthenticationProvider" />

</authentication
-
manager>

Create a custom entry point

The entry point
defines

the URL where user will be redirected to after authentication process
failed. To configure a custom entry point, you need to use
entry
-
point
-
ref

attribute

in Spring
Security http tag
,

s
ee

the
above
Spring Security configuration file

example. To customize
the
entry poinst, a

java class needs to implement
org.springframework.security.web.
AuthenticationEntryPoint interface. The following is a simple
example of the entry point implementation:


public class MyAuthenticationEntryPoint implements AuthenticationEn
tryPoint,
InitializingBean {


private String domainLogin;



public void afterPropertiesSet() throws Exception {



Assert.hasLength(domainLogin, "DomainLogin must be specified");


}



public void commence(HttpServletRequest request, HttpServletResponse

response, org.springframework.security.core.AuthenticationException ae)
throws IOException, ServletException {



String redirectUrl = domainLogin;



response.sendRedirect(response.encodeRedirectURL(redirectUrl));


}



/**


* @return the domainLogin


*/


public String getDomainLogin() {


return domainLogin;


}



/**


* @param domainLogin the domainLogin to set


*/


public void setDomainLogin(String domainLogin) {


this.domainLogin = domainLogin;


}

}


The following is the example of initialize the bean of entry point class in the Spring
configuration file.


<bean id="customEntryPoint"
class="au.com.aaf.tpac.security.MyAuthenticationEntryPoint">


<property name="domainLogin" value="error.htm"/>

</bean>

Create a
Pre Authentication Filter

The pre authentication filter is
the entry point
in
the secur
ity process.

It is the class where Service
Provider attributes can be accessed and
then
these attributes are passed to the other classes in the
Spring Security Framework.
To use a customized pre
-
authentication filter, please see the
Spring
Security configuration file example above. The following is an example
using default Spring
implementati
on of pre authentication filter:


<bean id="preauthenticationFilter"
class="org.springframework.security.web.authentication.preauth.RequestHeaderA
uthenticationFilter">


<property name="principalRequestHeader" value="REMOTE_USER"/>


<property name
="authenticationManager" ref="authenticationManager" />


</bean>


The principalRequestHeader

property is the value which is retrieved from the HTTP request
header. The name of the header is defined in the value property. In this case, the filter is
excepting the Service Provider to pass the REMOTE_USER header variable. The
REMOTE_USER attribute i
s defined in SP and it contains an authenticated username.

The
authenticationManager property defines what authentication provider and user detail service to
use in the filter.

To use more than one attribute in the filter, you can create your own filter by

extending this filter class or its parent
class
AbstractPreAuthenticatedProcessingFilter
.


Define a logout handler


To Logout the web application, we can use existing Spring

logout facility and the only change
required is to redirect user to the SP logout handler as user needs to be logged out by SP as well.

See the following example:



<logout invalidate
-
session="true" logout
-
success
-
url="http://localhost/Shibboleth.sso/Lo
gout" logout
-
url="/logout"/>



The url property defines the
SP
logout
handler URL.


Create
an
authentication provider

Spring security framework has a default authentication provider and t
his authentication provider
will not perform any checks on
authentication requests, as they should already be pre
-
authenticated

by SP
.
You can create your own implementation or extend this class if you want to
have extra
checks
. The following is the example of creating a bean of the default authentication
provider
:



<bean id="myAuthenticationProvider"
class="
org.springframework.security.web.authentication.preauth.
PreAuthenticatedAuthenticationProvider
">


<property name="preAuthenticatedUserDetailsService"
ref="myUserDetailsService"/>


</bean>

The
preAuthenticatedUserDetailsService

defines a user details service to use.

Create user details service

The user details service is responsible to returns a user object in the web application. Therefore,
you can use this class to load user object from any da
ta storage such as database based on the
attributes passed from service provider. The authentication object is an internal object

in the
Spring security framework and it is
created

by the pre authentication filter
. It has the same
function as a user objec
t in an application

and used as a user object in the Spring security
framework to do authentication and authorization
. The following example demonstrates how to
load a user object based on a username. You also need to create a UserService class to support
the following example.

If the web application requires authorization, you can also pass access
control information through an array of GrantedAuthority to the UserDetail class constructor.
This array is used in the Authorization provider to further check w
hether a user has the right
permission level to access the resource.

public class MyUserDetailsService implements AuthenticationUserDetailsService
{


private UserService userService;



public UserDetails loadUserDetails(Authentication a) throws
UsernameNotFoundException {


String username = (String) a.getPrincipal();



User user = userService.getUserNyName(username);



if (user == null) {


throw new UsernameNotFoundException("Cannot find username in the
system.");


}



UserDet
ails userDetails = new


org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),


user.isEnabled(), user.isAccountNonExpired(),
user.isCredentialsNonExpired(),


user.isAccountNonLocked(), user.getAutho
rities()) ;



return userDetails;


}



/**


* @return the userService


*/


public UserService getUserService() {


return userService;


}



/**


* @param userService the userService to set


*/


public void setUserService(UserService us
erService) {


this.userService = userService;


}

}


The following
illustrates how to initialize a bean of user detail service class.



<bean id="myAuthenticationProvider"
class="au.com.aaf.tpac.security.MyAuthenticationProvider">


<
property name="preAuthenticatedUserDetailsService"
ref="myUserDetailsService"/>


</bean>


Create
an
authorization provider

If the web application
requires an authorization service, an authorization provider can be created.
The following example
uses
a
default authorization provider and
it can be referenced
in the
access
-
decision
-
manager
-
ref

property

in the http

Spring Security

tag
.

Example can be
found in the Spring Security configuration file example mentioned above.

The R
ol
eVoter and
AuthenticatedVoter classes are the default Spring Security implementation, which perform
various role check functions. You can customize these voter classes to implement your own role
check functions

by implementing
org.springframework.security.access.Acce
ssDecisionVoter

interface
.



<bean class="org.springframework.security.access.vote.AffirmativeBased"
id="affirmativeBased">


<property name="decisionVoters">


<list>


<ref bean="roleVoter"/>


<ref bean="authenticatedVoter"/>



</list>


</property>


</bean>



<bean class="

org.springframework.security.access.vote.RoleVoter


" id="roleVoter"/>


<bean class="org.springframework.security.access.vote.AuthenticatedVoter"
id="authenticatedVoter"/>