6. web.xml
● Spring Security is implemented as a filter chain, so the
<filter-mapping> elements are the important ones:
● charEncodingFilter
● hiddenHttpMethod
● AssetPipelineFilter
● grailsWebRequest
● springSecurityFilterChain
● urlMapping
● grailsCacheFilter
7. web.xml
● Spring Security is implemented as a filter chain, so the
<filter-mapping> elements are the important ones:
● charEncodingFilter
● hiddenHttpMethod
● AssetPipelineFilter
● grailsWebRequest
● springSecurityFilterChain
● urlMapping
● grailsCacheFilter
8. web.xml - charEncodingFilter
Prevents this
●
org.springframework.web.filter.DelegatingFilterProxy
● Uses the "characterEncodingFilter" bean
(org.springframework.web.filter.CharacterEncodingFilter)
defined in WEB-INF/applicationContext.xml (the
“parent” context)
● request.setCharacterEncoding("utf-8");
● response.setCharacterEncoding("utf-8");
9. web.xml - hiddenHttpMethod
String httpMethod = getHttpMethodOverride(request);
filterChain.doFilter(
new HttpMethodRequestWrapper(httpMethod, request),
response);
●
org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter
● <g:form controller="book" method="DELETE">
● See the section on REST in the Grails reference docs
10. web.xml - AssetPipelineFilter
● asset.pipeline.grails.AssetPipelineFilter
● Manages minification, etc. for the asset-pipeline plugin(s)
22. springSecurityFilterChain - filterInvocationInterceptor
● Delegates to an AccessDecisionManager
(grails.plugin.springsecurity.access.vote.
AuthenticatedVetoableDecisionManager) to call
each registered
o.s.s.access.AccessDecisionVoter
25. springSecurityFilterChain - filterInvocationInterceptor
● grails.plugin.springsecurity.web.access.expression.
WebExpressionVoter looks for a
WebExpressionConfigAttribute and evaluates its
expression if found
● grails.plugin.springsecurity.access.vote.
ClosureVoter looks for a Closure and invokes it to
determine how to vote
26. springSecurityFilterChain - filterInvocationInterceptor
● This is caught by the exceptionTranslationFilter
● If the Authentication is anonymous, stores a
SavedRequest in the HTTP session and calls
authenticationEntryPoint.commence(request,
response, reason)
● The authenticationEntryPoint is a
grails.plugin.springsecurity.web.authentication.
AjaxAwareAuthenticationEntryPoint
● This issues a redirect to the login page, by default
/login/auth
if (denyCount > 0) {
throw new AccessDeniedException("Access is denied");
}
28. Customizing the Plugin
● Simple; not always clear how to customize; many
options aren't exposed
● In contrast, the plugin explicitly defines every bean and
exposes nearly all properties
● See SpringSecurityCoreGrailsPlugin.groovy
for the details
31. Overriding Beans
● Building the Spring ApplicationContext
Core pluginsCore plugins Installed pluginsInstalled plugins resources.groovyresources.groovy
32. Overriding Beans
● Gross oversimplifications:
● The ApplicationContext is like a Map; the keys are
bean names and the values are bean instances
● Defining a bean with the same name as an earlier bean
replaces the previous, just like Map.put(key,
value) does
33. Overriding Beans
● Gross oversimplifications:
● The ApplicationContext is like a Map; the keys are
bean names and the values are bean instances
● Defining a bean with the same name as an earlier bean
replaces the previous, just like Map.put(key,
value) does
34. Overriding Beans
● To change how a bean works:
● Subclass the current class
● Or subclass a similar class that's closer to what you need
●
Or implement the interface directly
● Then register yours in grails-app/
conf/spring/resources.groovy
37. Customizing Bean Properties
● In addition to declaring every bean, nearly all properties
are configured from default values in the plugin's
grails-
app/conf/DefaultSecurityConfig.groovy
● DO NOT EDIT DefaultSecurityConfig.groovy
38. Customizing Bean Properties
● All properties can be overridden in your app's
Config.groovy
● Be sure to add the grails.plugin.springsecurity
prefix
●
Don't replace a bean if all you need to change is one or
more properties
41. Customizing Bean Properties
class BootStrap {
def authenticationProcessingFilter
def myAuthenticationFailureHandler
def init = {
authenticationProcessingFilter.authenticationFailureHandler =
myAuthenticationFailureHandler
}
}
● Can also configure beans in BootStrap.groovy, e.g. to
avoid redefining a whole bean in resources.groovy just
to change one dependency:
44. Custom UserDetailsService
● General workflow:
● Create a custom
o.s.s.core.userdetails.UserDetailsService
(grails.plugin.springsecurity.userdetails.
GrailsUserDetailsService) implementation
● Directly implement the interface (best)
● or extend grails.plugin.springsecurity.userdetails.
GormUserDetailsService (ok, but usually cleaner to implement
the interface)
45. Custom UserDetailsService
● General workflow (cont.):
● Create a custom implementation of
o.s.s.core.userdetails.UserDetails
● Extend
grails.plugin.springsecurity.userdetails.GrailsUser
● or extend o.s.s.core.userdetails.User
● or directly implement the interface
46. Custom UserDetailsService
● General workflow (cont.):
● Register the bean override in grails-
app/conf/spring/resources.groovy:
import com.mycompany.myapp.MyUserDetailsService
beans = {
userDetailsService(MyUserDetailsService)
}
48. Custom AuthenticationProvider
● General workflow:
● Create a custom
o.s.s.authentication.AuthenticationProvider
implementation
● Extend one that's similar, e.g.
o.s.s.authentication.dao.DaoAuthenticationProvider
● or directly implement the interface
49. Custom AuthenticationProvider
● General workflow (cont.):
● You'll probably want a custom
org.springframework.security.core.Authentication
● Extend an existing implementation, e.g.
o.s.s.authentication.UsernamePasswordAuthenticationToken
● or directly implement the interface
50. Custom AuthenticationProvider
● General workflow (cont.):
● If you're using a custom Authentication, you'll need a filter to
create it
● Create a custom javax.servlet.Filter implementation
● Best to extend org.springframework.web.filter.GenericFilterBean
● or one that's similar, e.g.
o.s.s.web.authentication.UsernamePasswordAuthenticationFilter
● Or directly implement the interface
51. Custom AuthenticationProvider
● Registering the custom classes
● If you're replacing functionality, register bean overrides in
resources.groovy
● If you're adding an alternate authentication option (e.g. for only some
URLs)
● Register the beans in resources.groovy
● Register the provider as described in docs section “Authentication Providers”
●
Register the filter in its position as described in docs section “Filters”
53. Custom Post-logout Behavior
● Recall that logout is processed by MutableLogoutFilter
after request for /j_spring_security_logout
● handler.logout(request, response, auth) is
called for each LogoutHandler
● then redirect to post-logout url (by default “/”)
54. Custom Post-logout Behavior
● The default LogoutHandler implementations are
●
o.s.s.web.authentication.rememberme.TokenBasedRememberMeServices
● Deletes the remember-me cookie
●
o.s.s.web.authentication.logout.SecurityContextLogoutHandler
● Invalidates the HttpSession
● Removes the SecurityContext from the
SecurityContextHolder
55. Custom Post-logout Behavior
● Redirect is triggered by
● logoutSuccessHandler.onLogoutSuccess(request,
response, auth)
● LogoutSuccessHandler is an instance of
o.s.s.web.authentication.logout.SimpleUrlLogoutSuccessHandler
56. Custom Post-logout Behavior
● To add logic to dynamically determine redirect url:
● Subclass SimpleUrlLogoutSuccessHandler
● Since the Authentication isn't available in
determineTargetUrl, override onLogoutSuccess and set it
in a ThreadLocal
61. Customization Overview
● Subclass or replace filters in the chain:
● SecurityContextPersistenceFilter
● MutableLogoutFilter
● RequestHolderAuthenticationFilter
(UsernamePasswordAuthenticationFilter)
● SecurityContextHolderAwareRequestFilter
● RememberMeAuthenticationFilter
● AnonymousAuthenticationFilter
● ExceptionTranslationFilter
● FilterSecurityInterceptor
62. Customization Overview
● Remove filter(s) from the chain
● Not recommended
● Add filter(s) to the chain
● Add/remove/replace LogoutHandler(s)
● Add/remove/replace AccessDecisionVoter(s)
● Add/remove/replace AuthenticationProvider(s)
63. Customization Overview
● Customize a filter or AuthenticationProvider's dependency
● e.g. custom UserDetailsService
● Don't write code if you can customize properties or
BootStrap.groovy
● Read the Spring Security documentation
● Print the PDF and read it on your commute
● Ask for help on the Grails User mailing list