Spring Security 3.
Authentication and Authorization
Agenda
Authentication – LDAP & Database combined
solution
Authentication – Remember-me service
Authorization – Access Control Lists
Authentication
Authenticate users using an LDAP server
Read user information, including roles, from
custom database
Authentication Objects
Authentication Manager
Declaration
<authentication-manager alias="authenticationManager">
<authentication-provider ref='ldapAuthProvider'/>
<authentication-provider>
<user-service>
<user name="admin" password="sandtp"
authorities="ROLE_USER, ROLE_ADMIN"
/>
</user-service>
</authentication-provider>
</authentication-manager>
LDAP Authentication Provider
Declaration
<beans:bean id="ldapAuthProvider"
class="[Link]
[Link]">
<beans:constructor-arg
ref="bindAuthenticator" />
<beans:constructor-arg
ref="authoritiesPopulator" />
</beans:bean>
Bind Authenticator Declaration
<beans:bean id="bindAuthenticator"
class="[Link]">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userDnPatterns">
<beans:list>
<beans:value>sAMAccountName={0}</beans:value>
</beans:list>
</beans:property>
<beans:property name="userSearch" ref="userSearch" />
</beans:bean>
<beans:bean id="contextSource"
class="[Link]">
<beans:constructor-arg value="ldap://[Link]/DC=sntsoftware,DC=ro" />
<beans:property name="userDn" value="CN=[Link],CN=Users,DC=sntsoftware,DC=ro" />
<beans:property name="password" value="sandtp" />
</beans:bean>
<beans:bean id="userSearch"
class="[Link]">
<beans:constructor-arg index="0" value="" />
<beans:constructor-arg index="1" value="(sAMAccountName={0})" />
<beans:constructor-arg index="2" ref="contextSource" />
</beans:bean>
Authorities Populator
Declaration
<beans:bean id="authoritiesPopulator"
class="[Link]
[Link]
sPopulator">
<beans:constructor-arg
ref="userDetailsService"/>
</beans:bean>
UserDetailsService Declaration
<beans:bean id="userDetailsService"
class="[Link]">
<beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
<bean id="dataSource" class="[Link]"
destroy-method="close">
<property name="driverClassName" value="[Link]" />
<property name="url" value="jdbc:mysql://bart/voucher_schema?
createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding
=utf-8" />
<property name="username" value="root" />
<property name="password" value="sandtp-d" />
<property name="maxActive" value="100" />
<property name="maxWait" value="1000" />
<property name="poolPreparedStatements" value="true" />
<property name="defaultAutoCommit" value="true" />
</bean>
Database Schema for
JdbcDaoImpl
Remember-me Services
Spring Security offers 2 implementations:
Simple hash-based token
Persistent token
Remember-me : Simple hash-
based token
Remember-me : Persistent
Token
Remember-me Objects
Remember-me : Persistent
Token - Configuration
<beans:bean id="rememberMeServices"
class="[Link].P
ersistentTokenBasedRememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="tokenRepository" ref="jdbcTokenRepository" />
<beans:property name="key" value="e37f4b31-0c45-11dd-bd0b-
0800200c9a66" />
</beans:bean>
<beans:bean id="jdbcTokenRepository"
class="[Link].J
dbcTokenRepositoryImpl">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
Database Schema for
JdbcDaoImpl
Agenda
Authentication – LDAP & Database combined
solution
Authentication – Remember-me service
Authorization – Access Control Lists
Spring Security Access
Control Lists (ACLs)
authorization = grant access rights to
authenticated users
often the role is not enough to make
authorization decisions
example: manager can only approve
requests from employees in his own
department
ACL: authorization decision per-user, per-
object and per-operation basis
ACLs (cont)
@Secured({"ROLE_ADMIN", "ACL_OBJECT_READ", "AFTER_ACL_READ"})
MySecuredObject getSecuredObject(MySecuredObject obj);
2 types of verification:
Before invocation check access rights on
parameters
after invocation check access rights on returned
object
if access not granted AccessDeniedException
ACL Database Schema
ACL Database Schema (cont)
ACL_ENTRY.mask
ACL Data Model
ACL Service – Object Model
ACL Service – Declaration
(MySQL)
<beans:bean id="aclService"
class="[Link]
rvice">
<beans:constructor-arg ref="dataSource"/>
<beans:constructor-arg ref="lookupStrategy"/>
<beans:constructor-arg ref="aclCache"/>
<beans:property name="classIdentityQuery" value="SELECT
@@IDENTITY"/>
<beans:property name="sidIdentityQuery" value="SELECT
@@IDENTITY"/>
</beans:bean>
Access Decision Manager
@Secured({"ROLE_ADMIN", "ACL_OBJECT_READ", "AFTER_ACL_READ"})
public SecuredObject getSecuredObject(SecuredObject obj);
Access Decision Manager -
Declaration
<global-method-security secured-
annotations="enabled" access-decision-manager-
ref="businessAccessDecisionManager">
<after-invocation-provider ref="afterAclRead"/>
<after-invocation-provider
ref="afterAclCollectionRead"/>
</global-method-security>
Access Decision Manager –
Declaration (cont)
<beans:bean id="businessAccessDecisionManager"
class="[Link]
ed">
<beans:property name="allowIfAllAbstainDecisions"
value="true"/>
<beans:property name="decisionVoters">
<beans:list>
<beans:ref local="roleVoter"/>
<beans:ref local="aclObjectReadVoter"/>
</beans:list>
</beans:property>
</beans:bean>
Access Decision Manager –
Voters Configuration
<beans:bean id="roleVoter"
class="[Link]"/>
<beans:bean id="aclObjectReadVoter"
class="[Link]">
<beans:constructor-arg ref="aclService"/>
<beans:constructor-arg value="ACL_OBJECT_READ"/>
<beans:constructor-arg>
<beans:list>
<beans:ref local="aclCumulativeReadAdminPermission"/>
</beans:list>
</beans:constructor-arg>
<beans:property name="processDomainObjectClass"
value="[Link]"/>
</beans:bean>
Access Decision Manager –
Custom Permission
<beans:bean id="aclCumulativeReadAdminPermission"
class="[Link]">
</beans:bean>
package [Link];
import [Link];
public class ReadAdminCumulativePermission extends
[Link] {
public ReadAdminCumulativePermission() {
set([Link]);
set([Link]);
}
}
Access Decision Manager –
how does it work?
@Secured({"ROLE_ADMIN", "ACL_OBJECT_READ",
"AFTER_ACL_READ"})
public SecuredObject getSecuredObject(SecuredObject obj);
AclEntryVoter(AclService aclService,
[Link] processConfigAttribute,
Permission[] requirePermission)
boolean supports([Link]<?> clazz)
boolean supports(ConfigAttribute attribute)
int vote(Authentication authentication,
[Link] object,
[Link]<ConfigAttribute> attributes)
Access Decision Manager –
Cumulative Permissions Issue
Matching for permissions is done by Spring
Framework using “==”
Suppose Read and Write permissions are set
If you ask for isGranted(READ), it will not be
allowed!
You need to ask isGranted(READ && WRITE)
Solutions:
- modify the corresponding Spring Security code
- Enhancement provided in Spring Security 3.1:
[Link]
After Invocation Manager
After Invocation Providers
<global-method-security secured-
annotations="enabled" access-decision-manager-
ref="businessAccessDecisionManager">
<after-invocation-provider ref="afterAclRead"/>
<after-invocation-provider
ref="afterAclCollectionRead"/>
</global-method-security>
After Invocation Providers
(cont)
<beans:bean id="afterAclRead"
class="[Link]">
<beans:constructor-arg ref="aclService"/>
<beans:constructor-arg>
<beans:list>
<beans:ref local="aclCumulativeReadAdminPermission"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="afterAclCollectionRead"
class="[Link]
lteringProvider">
<beans:constructor-arg ref="aclService"/>
<beans:constructor-arg>
<beans:list>
<beans:ref local="aclCumulativeReadAdminPermission"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
Thank you!
[Link]
security/site/docs/3.0.x/reference/springse
[Link]
[Link]
security/site/docs/3.0.x/apidocs/