SlideShare une entreprise Scribd logo
1  sur  67
Télécharger pour lire hors ligne
Hacking the Grails Spring 
    Security Plugins
      Burt Beckwith
       SpringSource
CONFIDENTIAL   2
web.xml




 CONFIDENTIAL   3
web.xml


 Spring Security is implemented as a filter chain, so the
  <filter-mapping> elements are the important ones:
  • charEncodingFilter

  • hiddenHttpMethod

  • grailsWebRequest

  • springSecurityFilterChain

  • reloadFilter

  • sitemesh

  • urlMapping



                                    CONFIDENTIAL             4
web.xml


 Spring Security is implemented as a filter chain, so the
  <filter-mapping> elements are the important ones:
  • charEncodingFilter

  • hiddenHttpMethod

  • grailsWebRequest

  • springSecurityFilterChain
  • reloadFilter

  • sitemesh

  • urlMapping



                                    CONFIDENTIAL             5
web.xml - charEncodingFilter


 org.springframework.web.filter.DelegatingFilterProxy

 Uses the "characterEncodingFilter" bean
  (org.springframework.web.filter.CharacterEncodingFilter) defined
  in applicationContext.xml (the “parent” context)

 request.setCharacterEncoding("utf-8");

 response.setCharacterEncoding("utf-8");




                                       CONFIDENTIAL                  6
web.xml - hiddenHttpMethod

 org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter

  String httpMethod = getHttpMethodOverride(request);
  filterChain.doFilter(
     new HttpMethodRequestWrapper(httpMethod, request),
     response);

 <g:form controller="book" method="DELETE">

 See section “13.1 REST” in the docs




                                       CONFIDENTIAL               7
web.xml - grailsWebRequest

 org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter

 LocaleContextHolder.setLocale(request.getLocale());
 GrailsWebRequest webRequest = new GrailsWebRequest(
        request, response, getServletContext());
 configureParameterCreationListeners(webRequest);

 try {
    WebUtils.storeGrailsWebRequest(webRequest);

     // Set the flash scope instance to its next state
     FlashScope fs = webRequest.getAttributes().getFlashScope(request);
     fs.next();

     filterChain.doFilter(request, response);
 }
 finally {
    webRequest.requestCompleted();
    WebUtils.clearGrailsWebRequest();
    LocaleContextHolder.setLocale(null);
 }


                                      CONFIDENTIAL                    8
web.xml - springSecurityFilterChain

 org.springframework.web.filter.DelegatingFilterProxy


 Uses the "springSecurityFilterChain" bean defined by the plugin

  (org.springframework.security.web.FilterChainProxy)




                                       CONFIDENTIAL                 9
web.xml - springSecurityFilterChain


 Typical filter beans:
  • securityContextPersistenceFilter

  • logoutFilter

  • authenticationProcessingFilter

  • securityContextHolderAwareRequestFilter

  • rememberMeAuthenticationFilter

  • anonymousAuthenticationFilter

  • exceptionTranslationFilter

  • filterInvocationInterceptor



                                       CONFIDENTIAL   10
web.xml - reloadFilter

 org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter


 No longer used in 2.0+

 “Copies resources from the source on content change and manages

  reloading if necessary.”

 GrailsApplication application = (GrailsApplication)context.getBean(
       GrailsApplication.APPLICATION_ID);
 if (!application.isInitialised()) {
    application.rebuild();
    GrailsRuntimeConfigurator config = new GrailsRuntimeConfigurator(
       application, parent);
    config.reconfigure(context, getServletContext(), true);
 }



                                        CONFIDENTIAL                        11
web.xml - sitemesh

 org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter


 Subclass of com.opensymphony.sitemesh.webapp.SiteMeshFilter

 Renders Sitemesh templates/layouts




                                       CONFIDENTIAL             12
web.xml - urlMapping

 org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter


 Matches requested url to the correct controller/action/view/error code

 Based on mappings in grails-app/conf/UrlMappings.groovy




                                        CONFIDENTIAL                       13
springSecurityFilterChain




          CONFIDENTIAL      14
springSecurityFilterChain - securityContextPersistenceFilter


 org.springframework.security.web.context.SecurityContextPersistenceFilter


 Retrieves the SecurityContext from the HTTP session (under the

  ”SPRING_SECURITY_CONTEXT” key) or creates a new empty one


 Stores the context in the holder: SecurityContextHolder.setContext()

 Removes the context after request




                                      CONFIDENTIAL                            15
springSecurityFilterChain - logoutFilter


 org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter


 If uri is ”/j_spring_security_logout” calls

  handler.logout(request, response, auth) for each

  o.s.s.web.authentication.logout.LogoutHandler             and redirects to post-

  logout url (by default ”/”)




                                        CONFIDENTIAL                                 16
springSecurityFilterChain - authenticationProcessingFilter


 org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter

  (extends o.s.s.web.authentication.UsernamePasswordAuthenticationFilter)

 Sets the request and response in the SecurityRequestHolder

  ThreadLocal fields (custom plugin functionality)

 If uri is ”/j_spring_security_check” calls

  attemptAuthentication()




                                       CONFIDENTIAL                                17
springSecurityFilterChain - securityContextHolderAwareRequestFilter


 o.s.s.web.servletapi.SecurityContextHolderAwareRequestFilter


 Configures a request wrapper which implements the servlet API security

  methods (getRemoteUser, getUserPrincipal, isUserInRole)


     chain.doFilter(new SecurityContextHolderAwareRequestWrapper(
        request, rolePrefix),
        response);




                                      CONFIDENTIAL                         18
springSecurityFilterChain - rememberMeAuthenticationFilter


 o.s.s.web.authentication.rememberme.RememberMeAuthenticationFilter


 If not logged in, attempt to login from the

  remember-me cookie




                                     CONFIDENTIAL                      19
springSecurityFilterChain - anonymousAuthenticationFilter


 o.s.s.web.authentication.AnonymousAuthenticationFilter


 If not logged in creates an AnonymousAuthenticationToken and

  registers it as the Authentication in the SecurityContext




                     https://secure.flickr.com/photos/gaelx/5445598436/

                                          CONFIDENTIAL                    20
springSecurityFilterChain - exceptionTranslationFilter


 o.s.s.web.access.ExceptionTranslationFilter


 Handles AccessDeniedException and AuthenticationException

 For AuthenticationException will invoke the

  authenticationEntryPoint

 For AccessDeniedException invoke the

  authenticationEntryPoint if anonymous, otherwise delegate to

  o.s.s.web.access.AccessDeniedHandler




                                     CONFIDENTIAL                21
springSecurityFilterChain - filterInvocationInterceptor


 o.s.s.web.access.intercept.FilterSecurityInterceptor


 Determines the o.s.s.access.SecurityConfig collection for the

  request from FilterInvocationSecurityMetadataSource

  (AnnotationFilterInvocationDefinition,

  InterceptUrlMapFilterInvocationDefinition, or

  RequestmapFilterInvocationDefinition)




                                       CONFIDENTIAL               22
springSecurityFilterChain - filterInvocationInterceptor


 Delegates to an AccessDecisionManager

 (org.codehaus.groovy.grails.plugins.springsecurity.

 AuthenticatedVetoableDecisionManager) to call each registered

 o.s.s.access.AccessDecisionVoter




                               CONFIDENTIAL                      23
springSecurityFilterChain - filterInvocationInterceptor


 o.s.s.access.vote.AuthenticatedVoter works with

 “IS_AUTHENTICATED_FULLY”, “IS_AUTHENTICATED_REMEMBERED”,

 and “IS_AUTHENTICATED_ANONYMOUSLY”




                              CONFIDENTIAL                  24
springSecurityFilterChain - filterInvocationInterceptor


 o.s.s.access.vote.RoleHierarchyVoter finds the

 GrantedAuthority instances from the Authentication, checks

 for matches with required roles




                                   CONFIDENTIAL               25
springSecurityFilterChain - filterInvocationInterceptor


 org.codehaus.groovy.grails.plugins.springsecurity.

 WebExpressionVoter looks for a

 WebExpressionConfigAttribute and evaluates its expression if

 found




                                CONFIDENTIAL                    26
springSecurityFilterChain - filterInvocationInterceptor
                               Common built-in expressions
   Expression                         Description
   hasRole([role])                    Returns true if the current principal has the specified
                                      role.
   hasAnyRole([role1,role2])          Returns true if the current principal has any of the
                                      supplied roles (given as a comma-separated list of
                                      strings)
   principal                          Allows direct access to the principal object representing
                                      the current user
   authentication                     Allows direct access to the current Authentication object
                                      obtained from the SecurityContext
   permitAll                          Always evaluates to true
   denyAll                            Always evaluates to false
   isAnonymous()                      Returns true if the current principal is an anonymous
                                      user
   isRememberMe()                     Returns true if the current principal is a remember-me
                                      user
   isAuthenticated()                  Returns true if the user is not anonymous
   isFullyAuthenticated()             Returns true if the user is not an anonymous or a
                                      remember-me user

                                         CONFIDENTIAL                                             27
springSecurityFilterChain - filterInvocationInterceptor

   if (denyCount > 0) {
      throw new AccessDeniedException("Access is denied");
   }

 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 an
  org.codehaus.groovy.grails.plugins.springsecurity.

  AjaxAwareAuthenticationEntryPoint

 This issues a redirect to the login page, by default /login/auth

                                  CONFIDENTIAL                       28
Customizing the Plugin




         CONFIDENTIAL    29
Customizing the Plugin


 Traditional Spring Security uses XML with namespaced beans:


<beans:beans
     xmlns="http://www.springframework.org/schema/security"
     ...>

  <http auto-config="true">
    <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
  </http>

  <authentication-manager>
    <authentication-provider>
      <jdbc-user-service data-source-ref="dataSource" />
    </authentication-provider>
  </authentication-manager>

</beans:beans>


                                CONFIDENTIAL                   30
Customizing the Plugin


 Simple; not always clear how to customize; many options aren't exposed

 In contrast, the plugin explicitly defines every bean

 See SpringSecurityCoreGrailsPlugin.groovy for the details




                                    CONFIDENTIAL                           31
Overriding Beans




      CONFIDENTIAL   32
Overriding Beans

accessDecisionManager              filterInvocationInterceptor        roleVoter
accessDeniedHandler                logoutFilter                       runAsManager
anonymousAuthenticationFilter      logoutHandlers                     saltSource
anonymousAuthenticationProvider    logoutSuccessHandler               securityContextHolderAwareRequestFilter
authenticatedVoter                 objectDefinitionSource             securityContextLogoutHandler
authenticationDetailsSource        passwordEncoder                    securityContextPersistenceFilter
authenticationEntryPoint           portMapper                         securityEventListener
authenticationEventPublisher       portResolver                       sessionAuthenticationStrategy
authenticationFailureHandler       postAuthenticationChecks           springSecurityFilterChain
authenticationManager              preAuthenticationChecks            tokenRepository
authenticationProcessingFilter     redirectStrategy                   userCache
authenticationSuccessHandler       rememberMeAuthenticationFilter     userDetailsService
authenticationTrustResolver        rememberMeAuthenticationProvider   webExpressionHandler
authenticationUserDetailsService   rememberMeServices                 webExpressionVoter
daoAuthenticationProvider          requestCache                       webInvocationPrivilegeEvaluator
exceptionTranslationFilter         roleHierarchy




                                                    CONFIDENTIAL                                          33
Overriding Beans



 Building the Spring ApplicationContext




    Core plugins          Installed plugins   resources.groovy




                               CONFIDENTIAL                      34
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




                                       CONFIDENTIAL    35
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




                                         CONFIDENTIAL   36
Overriding Beans - resources.groovy



  beans = {

      saltSource(com.foo.bar.MySaltSource) {
         // bean properties
      }

      userDetailsService(com.foo.bar.MyUserDetailsService) {
         // bean properties
      }

      passwordEncoder(com.foo.bar.MyPasswordEncoder) {
         // bean properties
      }
  }




                             CONFIDENTIAL                      37
Customizing Bean Properties




           CONFIDENTIAL       38
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




                                    CONFIDENTIAL                              39
Customizing Bean Properties


 All properties can be overridden in app's Config.groovy

  • Be sure to add the grails.plugins.springsecurity prefix




 Don't replace a bean if all you need to change is one or more properties




                                   CONFIDENTIAL                              40
Customizing Bean Properties

active                                         dao.hideUserNotFoundExceptions             registerLoggerListener                    successHandler.useReferer
adh.ajaxErrorPage                              dao.reflectionSaltSourceProperty           rejectIfNoRule                            switchUser.exitUserUrl
adh.errorPage                                  digest.createAuthenticatedToken            rememberMe.alwaysRemember                 switchUser.switchFailureUrl
ajaxHeader                                     digest.key                                 rememberMe.cookieName                     switchUser.switchUserUrl
anon.key                                       digest.nonceValiditySeconds                rememberMe.key                            switchUser.targetUrl
anon.userAttribute                             digest.passwordAlreadyEncoded              rememberMe.parameter                      useBasicAuth
apf.allowSessionCreation                       digest.realmName                           rememberMe.persistent                     useDigestAuth
apf.continueChainBeforeSuccessfulAuthentication digest.useCleartextPasswords              rememberMe.persistentToken.domainClassName
                                                                                                                                  useHttpSessionEventPublisher
apf.filterProcessesUrl                         failureHandler.ajaxAuthFailUrl             rememberMe.persistentToken.seriesLength   userLookup.accountExpiredPropertyName
apf.passwordParameter                          failureHandler.defaultFailureUrl           rememberMe.persistentToken.tokenLength    userLookup.accountLockedPropertyName
apf.postOnly                                   failureHandler.exceptionMappings           rememberMe.tokenValiditySeconds           userLookup.authoritiesPropertyName
apf.usernameParameter                          failureHandler.useForward                  rememberMe.useSecureCookie                userLookup.authorityJoinClassName
atr.anonymousClass                             filterChain.stripQueryStringFromUrls       requestCache.createSession                userLookup.enabledPropertyName
atr.rememberMeClass                            interceptUrlMap                            requestCache.onlyOnGet                    userLookup.passwordExpiredPropertyName
auth.ajaxLoginFormUrl                          ipRestrictions                             requestMap.className                      userLookup.passwordPropertyName
auth.forceHttps                                logout.afterLogoutUrl                      requestMap.configAttributeField           userLookup.userDomainClassName
auth.loginFormUrl                              logout.filterProcessesUrl                  requestMap.urlField                       userLookup.usernamePropertyName
auth.useForward                                logout.handlerNames                        roleHierarchy                             useSecurityEventListener
authenticationDetails.authClass                password.algorithm                         secureChannel.definition                  useSessionFixationPrevention
authority.className                            password.bcrypt.logrounds                  securityConfigType                        useSwitchUserFilter
authority.nameField                            password.encodeHashAsBase64                sessionFixationPrevention.alwaysCreateSession
                                                                                                                                      useX509
basic.realmName                                portMapper.httpPort                        sessionFixationPrevention.migrate         voterNames
cacheUsers                                     portMapper.httpsPort                       successHandler.ajaxSuccessUrl             x509.checkForPrincipalChanges
controllerAnnotations.lowercase                providerManager.eraseCredentialsAfterAuthentication
                                                                                         successHandler.alwaysUseDefault            x509.continueFilterChainOnUnsuccessfulAuthentication
controllerAnnotations.matcher                  providerNames                              successHandler.defaultTargetUrl           x509.invalidateSessionOnPrincipalChange
controllerAnnotations.staticRules              redirectStrategy.contextRelative           successHandler.targetUrlParameter         x509.subjectDnRegex
                                                                                                                                    x509.throwExceptionWhenTokenRejected




                                                                                      CONFIDENTIAL                                                                             41
Customizing Bean Properties



                     grails-app/conf/Config.groovy:
grails.plugins.springsecurity.userLookup.userDomainClassName = '…'

grails.plugins.springsecurity.userLookup.authorityJoinClassName = '…'

grails.plugins.springsecurity.authority.className = '…'

grails.plugins.springsecurity.auth.loginFormUrl = '/log-in'

grails.plugins.springsecurity.apf.filterProcessesUrl = '/authenticate'

grails.plugins.springsecurity.logout.afterLogoutUrl = '/home'

grails.plugins.springsecurity.userLookup.usernamePropertyName = 'email'




                                 CONFIDENTIAL                           42
Customizing Bean Properties


 Can also configure beans in BootStrap.groovy, e.g. to avoid

 redefining a whole bean in resources.groovy just to change one

 dependency:

 class BootStrap {

     def authenticationProcessingFilter
     def myAuthenticationFailureHandler

     def init = { servletContext ->
        authenticationProcessingFilter.authenticationFailureHandler =
              myAuthenticationFailureHandler
     }
 }




                                 CONFIDENTIAL                           43
Custom UserDetailsService




          CONFIDENTIAL      44
Custom UserDetailsService


 Very common customization

 Documented in the plugin docs in section

  “11 Custom UserDetailsService”




                                   CONFIDENTIAL   45
Custom UserDetailsService


 General workflow:

 • Create a custom o.s.s.core.userdetails.UserDetailsService

   (o.c.g.g.p.s.GrailsUserDetailsService) implementation

   • Directly implement the interface (best)

   • or extend org.codehaus.groovy.grails.plugins.springsecurity.

     GormUserDetailsService (ok, but usually cleaner to implement the

     interface)




                                      CONFIDENTIAL                      46
Custom UserDetailsService


 General workflow (cont.):

  • Create a custom implementation of o.s.s.core.userdetails.UserDetails

    • Extend org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser

    • or extend o.s.s.core.userdetails.User

    • or directly implement the interface




                                        CONFIDENTIAL                        47
Custom UserDetailsService


 General workflow (cont.):

  • Register the bean override in grails-app/conf/spring/resources.groovy:



       import com.mycompany.myapp.MyUserDetailsService

       beans = {
          userDetailsService(MyUserDetailsService)
       }




                                   CONFIDENTIAL                              48
Custom AuthenticationProvider




            CONFIDENTIAL        49
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




                                       CONFIDENTIAL              50
Custom AuthenticationProvider


 General workflow (cont.):

  • You'll probably want a custom o.s.s.core.Authentication

    • Extend an existing implementation, e.g.

     o.s.s.authentication.UsernamePasswordAuthenticationToken


    • or directly implement the interface




                                        CONFIDENTIAL            51
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




                                       CONFIDENTIAL                              52
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 section “10 Authentication Providers” of

     the docs

   • Register the filter in its position as described in section “16 Filters” of the docs




                                        CONFIDENTIAL                                        53
Custom Post-logout Behavior




           CONFIDENTIAL       54
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 ”/”)




                                    CONFIDENTIAL                     55
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




                                     CONFIDENTIAL                       56
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




                                 CONFIDENTIAL                  57
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




                                    CONFIDENTIAL                           58
Custom Post-logout Behavior


 To add logic to dynamically determine redirect url (cont.):

private static final ThreadLocal<Authentication> AUTH_HOLDER =
     new ThreadLocal<Authentication>()
…
void onLogoutSuccess(...) throws ... {
   AUTH_HOLDER.set authentication
   try {
      super.handle(request, response, authentication)
   }
   finally {
      AUTH_HOLDER.remove()
   }
}




                                    CONFIDENTIAL                59
Custom Post-logout Behavior


 To add logic to dynamically determine redirect url (cont.):

  • Override determineTargetUrl

  protected String determineTargetUrl(...) {
     Authentication auth = AUTH_HOLDER.get()

      String url = super.determineTargetUrl(request, response)

      if (auth instanceof OrganizationAuthentication) {
         OrganizationAuthentication authentication = auth
         url = ...
      }

      url
  }



                                    CONFIDENTIAL                 60
Custom Post-logout Behavior


 To add logic to dynamically determine redirect url (cont.):

  • Redefine the logoutSuccessHandler bean in resources.groovy


    import com.mycompany.myapp.CustomLogoutSuccessHandler
    import o.c.g.g.plugins.springsecurity.SpringSecurityUtils

    beans = {

        def conf = SpringSecurityUtils.securityConfig

        logoutSuccessHandler(CustomLogoutSuccessHandler) {
           redirectStrategy = ref('redirectStrategy')
           defaultTargetUrl = conf.logout.afterLogoutUrl
        }
    }


                                    CONFIDENTIAL                 61
Customization Overview




         CONFIDENTIAL    62
Customization Overview


 Subclass or replace filters in the chain:
  • SecurityContextPersistenceFilter

  • MutableLogoutFilter

  • RequestHolderAuthenticationFilter
   (UsernamePasswordAuthenticationFilter)

  • SecurityContextHolderAwareRequestFilter

  • RememberMeAuthenticationFilter

  • AnonymousAuthenticationFilter

  • ExceptionTranslationFilter

  • FilterSecurityInterceptor

                                     CONFIDENTIAL   63
Customization Overview (cont)


 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)




                                    CONFIDENTIAL   64
Customization Overview (cont)


 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




                                     CONFIDENTIAL                        65
See http://burtbeckwith.com/blog/?p=1090 for
 a blog post on the previous talk in London




                    CONFIDENTIAL               66
Thank you




  CONFIDENTIAL   67

Contenu connexe

Tendances

Better than you think: Handling JSON data in ClickHouse
Better than you think: Handling JSON data in ClickHouseBetter than you think: Handling JSON data in ClickHouse
Better than you think: Handling JSON data in ClickHouseAltinity Ltd
 
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnects
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA InterconnectsRDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnects
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnectsinside-BigData.com
 
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster Performance
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster PerformanceWebinar: Strength in Numbers: Introduction to ClickHouse Cluster Performance
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster PerformanceAltinity Ltd
 
仮想マシンにおけるメモリ管理
仮想マシンにおけるメモリ管理仮想マシンにおけるメモリ管理
仮想マシンにおけるメモリ管理Akari Asai
 
IPFS introduction
IPFS introductionIPFS introduction
IPFS introductionGenta M
 
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Nagato Kasaki
 
Security and Privacy of Machine Learning
Security and Privacy of Machine LearningSecurity and Privacy of Machine Learning
Security and Privacy of Machine LearningPriyanka Aash
 
patroni-based citrus high availability environment deployment
patroni-based citrus high availability environment deploymentpatroni-based citrus high availability environment deployment
patroni-based citrus high availability environment deploymenthyeongchae lee
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기Arawn Park
 
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...Altinity Ltd
 
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfDeep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfAltinity Ltd
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013Vladimir Ivanov
 
A Day in the Life of a ClickHouse Query Webinar Slides
A Day in the Life of a ClickHouse Query Webinar Slides A Day in the Life of a ClickHouse Query Webinar Slides
A Day in the Life of a ClickHouse Query Webinar Slides Altinity Ltd
 
Cilium - Bringing the BPF Revolution to Kubernetes Networking and Security
Cilium - Bringing the BPF Revolution to Kubernetes Networking and SecurityCilium - Bringing the BPF Revolution to Kubernetes Networking and Security
Cilium - Bringing the BPF Revolution to Kubernetes Networking and SecurityThomas Graf
 
Using Time Window Compaction Strategy For Time Series Workloads
Using Time Window Compaction Strategy For Time Series WorkloadsUsing Time Window Compaction Strategy For Time Series Workloads
Using Time Window Compaction Strategy For Time Series WorkloadsJeff Jirsa
 
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディングTakuya ASADA
 
DoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDKDoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDKMarian Marinov
 
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSPostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSNoriyoshi Shinoda
 
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2 Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2 Alphorm
 

Tendances (20)

Better than you think: Handling JSON data in ClickHouse
Better than you think: Handling JSON data in ClickHouseBetter than you think: Handling JSON data in ClickHouse
Better than you think: Handling JSON data in ClickHouse
 
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnects
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA InterconnectsRDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnects
RDMA, Scalable MPI-3 RMA, and Next-Generation Post-RDMA Interconnects
 
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster Performance
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster PerformanceWebinar: Strength in Numbers: Introduction to ClickHouse Cluster Performance
Webinar: Strength in Numbers: Introduction to ClickHouse Cluster Performance
 
マスタリングTCP/IP ニフクラ編
マスタリングTCP/IP ニフクラ編マスタリングTCP/IP ニフクラ編
マスタリングTCP/IP ニフクラ編
 
仮想マシンにおけるメモリ管理
仮想マシンにおけるメモリ管理仮想マシンにおけるメモリ管理
仮想マシンにおけるメモリ管理
 
IPFS introduction
IPFS introductionIPFS introduction
IPFS introduction
 
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
 
Security and Privacy of Machine Learning
Security and Privacy of Machine LearningSecurity and Privacy of Machine Learning
Security and Privacy of Machine Learning
 
patroni-based citrus high availability environment deployment
patroni-based citrus high availability environment deploymentpatroni-based citrus high availability environment deployment
patroni-based citrus high availability environment deployment
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
 
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdfDeep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013JVM JIT-compiler overview @ JavaOne Moscow 2013
JVM JIT-compiler overview @ JavaOne Moscow 2013
 
A Day in the Life of a ClickHouse Query Webinar Slides
A Day in the Life of a ClickHouse Query Webinar Slides A Day in the Life of a ClickHouse Query Webinar Slides
A Day in the Life of a ClickHouse Query Webinar Slides
 
Cilium - Bringing the BPF Revolution to Kubernetes Networking and Security
Cilium - Bringing the BPF Revolution to Kubernetes Networking and SecurityCilium - Bringing the BPF Revolution to Kubernetes Networking and Security
Cilium - Bringing the BPF Revolution to Kubernetes Networking and Security
 
Using Time Window Compaction Strategy For Time Series Workloads
Using Time Window Compaction Strategy For Time Series WorkloadsUsing Time Window Compaction Strategy For Time Series Workloads
Using Time Window Compaction Strategy For Time Series Workloads
 
仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング仮想化環境におけるパケットフォワーディング
仮想化環境におけるパケットフォワーディング
 
DoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDKDoS and DDoS mitigations with eBPF, XDP and DPDK
DoS and DDoS mitigations with eBPF, XDP and DPDK
 
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSPostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVS
 
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2 Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2
Alphorm.com Formation Implémenter une PKI avec ADCS 2012 R2
 

En vedette

Groovy & Grails - From Scratch to Production
Groovy & Grails - From Scratch to Production Groovy & Grails - From Scratch to Production
Groovy & Grails - From Scratch to Production Tal Maayani
 
Hacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginHacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginBurt Beckwith
 
Advanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringAdvanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringBurt Beckwith
 
Geb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosperGeb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosperEsther Lozano
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...Burt Beckwith
 
GriffDnie (Griffon Demo)
GriffDnie (Griffon Demo)GriffDnie (Griffon Demo)
GriffDnie (Griffon Demo)Jorge Aguilera
 
Macro macro, burrito burrit
Macro macro, burrito burritMacro macro, burrito burrit
Macro macro, burrito burritMario García
 
Fun With Spring Security
Fun With Spring SecurityFun With Spring Security
Fun With Spring SecurityBurt Beckwith
 

En vedette (9)

Groovy & Grails - From Scratch to Production
Groovy & Grails - From Scratch to Production Groovy & Grails - From Scratch to Production
Groovy & Grails - From Scratch to Production
 
Hacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 PluginHacking the Grails Spring Security 2.0 Plugin
Hacking the Grails Spring Security 2.0 Plugin
 
Advanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and MonitoringAdvanced GORM - Performance, Customization and Monitoring
Advanced GORM - Performance, Customization and Monitoring
 
Geb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosperGeb+spock: let your functional tests live long and prosper
Geb+spock: let your functional tests live long and prosper
 
Little Did He Know ...
Little Did He Know ...Little Did He Know ...
Little Did He Know ...
 
De Java a Swift pasando por Groovy
De Java a Swift pasando por GroovyDe Java a Swift pasando por Groovy
De Java a Swift pasando por Groovy
 
GriffDnie (Griffon Demo)
GriffDnie (Griffon Demo)GriffDnie (Griffon Demo)
GriffDnie (Griffon Demo)
 
Macro macro, burrito burrit
Macro macro, burrito burritMacro macro, burrito burrit
Macro macro, burrito burrit
 
Fun With Spring Security
Fun With Spring SecurityFun With Spring Security
Fun With Spring Security
 

Similaire à Hacking the Grails Spring Security Plugins

Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring SecurityDzmitry Naskou
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsGR8Conf
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with SpringJoshua Long
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsBurt Beckwith
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Matt Raible
 
A Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in JavaA Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in JavaVMware Tanzu
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenJoshua Long
 
Integrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsIntegrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsDan Wahlin
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WAREFermin Galan
 
iOS Keychain by 흰, 민디
iOS Keychain by 흰, 민디iOS Keychain by 흰, 민디
iOS Keychain by 흰, 민디MINJICHO20
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & HibernateJiayun Zhou
 
EPAM IT WEEK: AEM & TDD. It's so boring...
EPAM IT WEEK: AEM & TDD. It's so boring...EPAM IT WEEK: AEM & TDD. It's so boring...
EPAM IT WEEK: AEM & TDD. It's so boring...Andrew Manuev
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Introduction to PicketLink
Introduction to PicketLinkIntroduction to PicketLink
Introduction to PicketLinkJBUG London
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depthVinay Kumar
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample applicationAntoine Rey
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Matt Raible
 

Similaire à Hacking the Grails Spring Security Plugins (20)

Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
Multi Client Development with Spring
Multi Client Development with SpringMulti Client Development with Spring
Multi Client Development with Spring
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
 
A Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in JavaA Series of Fortunate Events: Building an Operator in Java
A Series of Fortunate Events: Building an Operator in Java
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in HeavenSpring and Cloud Foundry; a Marriage Made in Heaven
Spring and Cloud Foundry; a Marriage Made in Heaven
 
Integrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight ApplicationsIntegrating Security Roles into Microsoft Silverlight Applications
Integrating Security Roles into Microsoft Silverlight Applications
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WARE
 
iOS Keychain by 흰, 민디
iOS Keychain by 흰, 민디iOS Keychain by 흰, 민디
iOS Keychain by 흰, 민디
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
Spring Security.ppt
Spring Security.pptSpring Security.ppt
Spring Security.ppt
 
EPAM IT WEEK: AEM & TDD. It's so boring...
EPAM IT WEEK: AEM & TDD. It's so boring...EPAM IT WEEK: AEM & TDD. It's so boring...
EPAM IT WEEK: AEM & TDD. It's so boring...
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Introduction to PicketLink
Introduction to PicketLinkIntroduction to PicketLink
Introduction to PicketLink
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depth
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
 
The most basic inline tag
The most basic inline tagThe most basic inline tag
The most basic inline tag
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
 

Plus de GR8Conf

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your TeamGR8Conf
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle GR8Conf
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with GebGR8Conf
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidGR8Conf
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the DocksGR8Conf
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsGR8Conf
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applicationsGR8Conf
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3GR8Conf
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGR8Conf
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEBGR8Conf
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCGR8Conf
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshopGR8Conf
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spockGR8Conf
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedGR8Conf
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGR8Conf
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and GroovyGR8Conf
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineGR8Conf
 

Plus de GR8Conf (20)

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your Team
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developer
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with Geb
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and Android
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the Docks
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature plugins
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applications
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloud
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEB
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPC
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshop
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem Revisited
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and Groovy
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual Machine
 

Dernier

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 

Dernier (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Hacking the Grails Spring Security Plugins

  • 1. Hacking the Grails Spring  Security Plugins Burt Beckwith SpringSource
  • 4. web.xml  Spring Security is implemented as a filter chain, so the <filter-mapping> elements are the important ones: • charEncodingFilter • hiddenHttpMethod • grailsWebRequest • springSecurityFilterChain • reloadFilter • sitemesh • urlMapping CONFIDENTIAL 4
  • 5. web.xml  Spring Security is implemented as a filter chain, so the <filter-mapping> elements are the important ones: • charEncodingFilter • hiddenHttpMethod • grailsWebRequest • springSecurityFilterChain • reloadFilter • sitemesh • urlMapping CONFIDENTIAL 5
  • 6. web.xml - charEncodingFilter  org.springframework.web.filter.DelegatingFilterProxy  Uses the "characterEncodingFilter" bean (org.springframework.web.filter.CharacterEncodingFilter) defined in applicationContext.xml (the “parent” context)  request.setCharacterEncoding("utf-8");  response.setCharacterEncoding("utf-8"); CONFIDENTIAL 6
  • 7. web.xml - hiddenHttpMethod  org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter String httpMethod = getHttpMethodOverride(request); filterChain.doFilter( new HttpMethodRequestWrapper(httpMethod, request), response);  <g:form controller="book" method="DELETE">  See section “13.1 REST” in the docs CONFIDENTIAL 7
  • 8. web.xml - grailsWebRequest  org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter LocaleContextHolder.setLocale(request.getLocale()); GrailsWebRequest webRequest = new GrailsWebRequest( request, response, getServletContext()); configureParameterCreationListeners(webRequest); try { WebUtils.storeGrailsWebRequest(webRequest); // Set the flash scope instance to its next state FlashScope fs = webRequest.getAttributes().getFlashScope(request); fs.next(); filterChain.doFilter(request, response); } finally { webRequest.requestCompleted(); WebUtils.clearGrailsWebRequest(); LocaleContextHolder.setLocale(null); } CONFIDENTIAL 8
  • 9. web.xml - springSecurityFilterChain  org.springframework.web.filter.DelegatingFilterProxy  Uses the "springSecurityFilterChain" bean defined by the plugin (org.springframework.security.web.FilterChainProxy) CONFIDENTIAL 9
  • 10. web.xml - springSecurityFilterChain  Typical filter beans: • securityContextPersistenceFilter • logoutFilter • authenticationProcessingFilter • securityContextHolderAwareRequestFilter • rememberMeAuthenticationFilter • anonymousAuthenticationFilter • exceptionTranslationFilter • filterInvocationInterceptor CONFIDENTIAL 10
  • 11. web.xml - reloadFilter  org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter  No longer used in 2.0+  “Copies resources from the source on content change and manages reloading if necessary.” GrailsApplication application = (GrailsApplication)context.getBean( GrailsApplication.APPLICATION_ID); if (!application.isInitialised()) { application.rebuild(); GrailsRuntimeConfigurator config = new GrailsRuntimeConfigurator( application, parent); config.reconfigure(context, getServletContext(), true); } CONFIDENTIAL 11
  • 12. web.xml - sitemesh  org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter  Subclass of com.opensymphony.sitemesh.webapp.SiteMeshFilter  Renders Sitemesh templates/layouts CONFIDENTIAL 12
  • 13. web.xml - urlMapping  org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter  Matches requested url to the correct controller/action/view/error code  Based on mappings in grails-app/conf/UrlMappings.groovy CONFIDENTIAL 13
  • 14. springSecurityFilterChain CONFIDENTIAL 14
  • 15. springSecurityFilterChain - securityContextPersistenceFilter  org.springframework.security.web.context.SecurityContextPersistenceFilter  Retrieves the SecurityContext from the HTTP session (under the ”SPRING_SECURITY_CONTEXT” key) or creates a new empty one  Stores the context in the holder: SecurityContextHolder.setContext()  Removes the context after request CONFIDENTIAL 15
  • 16. springSecurityFilterChain - logoutFilter  org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter  If uri is ”/j_spring_security_logout” calls handler.logout(request, response, auth) for each o.s.s.web.authentication.logout.LogoutHandler and redirects to post- logout url (by default ”/”) CONFIDENTIAL 16
  • 17. springSecurityFilterChain - authenticationProcessingFilter  org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter (extends o.s.s.web.authentication.UsernamePasswordAuthenticationFilter)  Sets the request and response in the SecurityRequestHolder ThreadLocal fields (custom plugin functionality)  If uri is ”/j_spring_security_check” calls attemptAuthentication() CONFIDENTIAL 17
  • 18. springSecurityFilterChain - securityContextHolderAwareRequestFilter  o.s.s.web.servletapi.SecurityContextHolderAwareRequestFilter  Configures a request wrapper which implements the servlet API security methods (getRemoteUser, getUserPrincipal, isUserInRole) chain.doFilter(new SecurityContextHolderAwareRequestWrapper( request, rolePrefix), response); CONFIDENTIAL 18
  • 19. springSecurityFilterChain - rememberMeAuthenticationFilter  o.s.s.web.authentication.rememberme.RememberMeAuthenticationFilter  If not logged in, attempt to login from the remember-me cookie CONFIDENTIAL 19
  • 20. springSecurityFilterChain - anonymousAuthenticationFilter  o.s.s.web.authentication.AnonymousAuthenticationFilter  If not logged in creates an AnonymousAuthenticationToken and registers it as the Authentication in the SecurityContext https://secure.flickr.com/photos/gaelx/5445598436/ CONFIDENTIAL 20
  • 21. springSecurityFilterChain - exceptionTranslationFilter  o.s.s.web.access.ExceptionTranslationFilter  Handles AccessDeniedException and AuthenticationException  For AuthenticationException will invoke the authenticationEntryPoint  For AccessDeniedException invoke the authenticationEntryPoint if anonymous, otherwise delegate to o.s.s.web.access.AccessDeniedHandler CONFIDENTIAL 21
  • 22. springSecurityFilterChain - filterInvocationInterceptor  o.s.s.web.access.intercept.FilterSecurityInterceptor  Determines the o.s.s.access.SecurityConfig collection for the request from FilterInvocationSecurityMetadataSource (AnnotationFilterInvocationDefinition, InterceptUrlMapFilterInvocationDefinition, or RequestmapFilterInvocationDefinition) CONFIDENTIAL 22
  • 23. springSecurityFilterChain - filterInvocationInterceptor  Delegates to an AccessDecisionManager (org.codehaus.groovy.grails.plugins.springsecurity. AuthenticatedVetoableDecisionManager) to call each registered o.s.s.access.AccessDecisionVoter CONFIDENTIAL 23
  • 24. springSecurityFilterChain - filterInvocationInterceptor  o.s.s.access.vote.AuthenticatedVoter works with “IS_AUTHENTICATED_FULLY”, “IS_AUTHENTICATED_REMEMBERED”, and “IS_AUTHENTICATED_ANONYMOUSLY” CONFIDENTIAL 24
  • 25. springSecurityFilterChain - filterInvocationInterceptor  o.s.s.access.vote.RoleHierarchyVoter finds the GrantedAuthority instances from the Authentication, checks for matches with required roles CONFIDENTIAL 25
  • 26. springSecurityFilterChain - filterInvocationInterceptor  org.codehaus.groovy.grails.plugins.springsecurity. WebExpressionVoter looks for a WebExpressionConfigAttribute and evaluates its expression if found CONFIDENTIAL 26
  • 27. springSecurityFilterChain - filterInvocationInterceptor Common built-in expressions Expression Description hasRole([role]) Returns true if the current principal has the specified role. hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings) principal Allows direct access to the principal object representing the current user authentication Allows direct access to the current Authentication object obtained from the SecurityContext permitAll Always evaluates to true denyAll Always evaluates to false isAnonymous() Returns true if the current principal is an anonymous user isRememberMe() Returns true if the current principal is a remember-me user isAuthenticated() Returns true if the user is not anonymous isFullyAuthenticated() Returns true if the user is not an anonymous or a remember-me user CONFIDENTIAL 27
  • 28. springSecurityFilterChain - filterInvocationInterceptor if (denyCount > 0) { throw new AccessDeniedException("Access is denied"); }  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 an org.codehaus.groovy.grails.plugins.springsecurity. AjaxAwareAuthenticationEntryPoint  This issues a redirect to the login page, by default /login/auth CONFIDENTIAL 28
  • 29. Customizing the Plugin CONFIDENTIAL 29
  • 30. Customizing the Plugin Traditional Spring Security uses XML with namespaced beans: <beans:beans xmlns="http://www.springframework.org/schema/security" ...> <http auto-config="true"> <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> </http> <authentication-manager> <authentication-provider> <jdbc-user-service data-source-ref="dataSource" /> </authentication-provider> </authentication-manager> </beans:beans> CONFIDENTIAL 30
  • 31. Customizing the Plugin  Simple; not always clear how to customize; many options aren't exposed  In contrast, the plugin explicitly defines every bean  See SpringSecurityCoreGrailsPlugin.groovy for the details CONFIDENTIAL 31
  • 32. Overriding Beans CONFIDENTIAL 32
  • 33. Overriding Beans accessDecisionManager filterInvocationInterceptor roleVoter accessDeniedHandler logoutFilter runAsManager anonymousAuthenticationFilter logoutHandlers saltSource anonymousAuthenticationProvider logoutSuccessHandler securityContextHolderAwareRequestFilter authenticatedVoter objectDefinitionSource securityContextLogoutHandler authenticationDetailsSource passwordEncoder securityContextPersistenceFilter authenticationEntryPoint portMapper securityEventListener authenticationEventPublisher portResolver sessionAuthenticationStrategy authenticationFailureHandler postAuthenticationChecks springSecurityFilterChain authenticationManager preAuthenticationChecks tokenRepository authenticationProcessingFilter redirectStrategy userCache authenticationSuccessHandler rememberMeAuthenticationFilter userDetailsService authenticationTrustResolver rememberMeAuthenticationProvider webExpressionHandler authenticationUserDetailsService rememberMeServices webExpressionVoter daoAuthenticationProvider requestCache webInvocationPrivilegeEvaluator exceptionTranslationFilter roleHierarchy CONFIDENTIAL 33
  • 34. Overriding Beans  Building the Spring ApplicationContext Core plugins Installed plugins resources.groovy CONFIDENTIAL 34
  • 35. 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 CONFIDENTIAL 35
  • 36. 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 CONFIDENTIAL 36
  • 37. Overriding Beans - resources.groovy beans = { saltSource(com.foo.bar.MySaltSource) { // bean properties } userDetailsService(com.foo.bar.MyUserDetailsService) { // bean properties } passwordEncoder(com.foo.bar.MyPasswordEncoder) { // bean properties } } CONFIDENTIAL 37
  • 38. Customizing Bean Properties CONFIDENTIAL 38
  • 39. 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 CONFIDENTIAL 39
  • 40. Customizing Bean Properties  All properties can be overridden in app's Config.groovy • Be sure to add the grails.plugins.springsecurity prefix  Don't replace a bean if all you need to change is one or more properties CONFIDENTIAL 40
  • 41. Customizing Bean Properties active dao.hideUserNotFoundExceptions registerLoggerListener successHandler.useReferer adh.ajaxErrorPage dao.reflectionSaltSourceProperty rejectIfNoRule switchUser.exitUserUrl adh.errorPage digest.createAuthenticatedToken rememberMe.alwaysRemember switchUser.switchFailureUrl ajaxHeader digest.key rememberMe.cookieName switchUser.switchUserUrl anon.key digest.nonceValiditySeconds rememberMe.key switchUser.targetUrl anon.userAttribute digest.passwordAlreadyEncoded rememberMe.parameter useBasicAuth apf.allowSessionCreation digest.realmName rememberMe.persistent useDigestAuth apf.continueChainBeforeSuccessfulAuthentication digest.useCleartextPasswords rememberMe.persistentToken.domainClassName useHttpSessionEventPublisher apf.filterProcessesUrl failureHandler.ajaxAuthFailUrl rememberMe.persistentToken.seriesLength userLookup.accountExpiredPropertyName apf.passwordParameter failureHandler.defaultFailureUrl rememberMe.persistentToken.tokenLength userLookup.accountLockedPropertyName apf.postOnly failureHandler.exceptionMappings rememberMe.tokenValiditySeconds userLookup.authoritiesPropertyName apf.usernameParameter failureHandler.useForward rememberMe.useSecureCookie userLookup.authorityJoinClassName atr.anonymousClass filterChain.stripQueryStringFromUrls requestCache.createSession userLookup.enabledPropertyName atr.rememberMeClass interceptUrlMap requestCache.onlyOnGet userLookup.passwordExpiredPropertyName auth.ajaxLoginFormUrl ipRestrictions requestMap.className userLookup.passwordPropertyName auth.forceHttps logout.afterLogoutUrl requestMap.configAttributeField userLookup.userDomainClassName auth.loginFormUrl logout.filterProcessesUrl requestMap.urlField userLookup.usernamePropertyName auth.useForward logout.handlerNames roleHierarchy useSecurityEventListener authenticationDetails.authClass password.algorithm secureChannel.definition useSessionFixationPrevention authority.className password.bcrypt.logrounds securityConfigType useSwitchUserFilter authority.nameField password.encodeHashAsBase64 sessionFixationPrevention.alwaysCreateSession useX509 basic.realmName portMapper.httpPort sessionFixationPrevention.migrate voterNames cacheUsers portMapper.httpsPort successHandler.ajaxSuccessUrl x509.checkForPrincipalChanges controllerAnnotations.lowercase providerManager.eraseCredentialsAfterAuthentication successHandler.alwaysUseDefault x509.continueFilterChainOnUnsuccessfulAuthentication controllerAnnotations.matcher providerNames successHandler.defaultTargetUrl x509.invalidateSessionOnPrincipalChange controllerAnnotations.staticRules redirectStrategy.contextRelative successHandler.targetUrlParameter x509.subjectDnRegex x509.throwExceptionWhenTokenRejected CONFIDENTIAL 41
  • 42. Customizing Bean Properties grails-app/conf/Config.groovy: grails.plugins.springsecurity.userLookup.userDomainClassName = '…' grails.plugins.springsecurity.userLookup.authorityJoinClassName = '…' grails.plugins.springsecurity.authority.className = '…' grails.plugins.springsecurity.auth.loginFormUrl = '/log-in' grails.plugins.springsecurity.apf.filterProcessesUrl = '/authenticate' grails.plugins.springsecurity.logout.afterLogoutUrl = '/home' grails.plugins.springsecurity.userLookup.usernamePropertyName = 'email' CONFIDENTIAL 42
  • 43. Customizing Bean Properties  Can also configure beans in BootStrap.groovy, e.g. to avoid redefining a whole bean in resources.groovy just to change one dependency: class BootStrap { def authenticationProcessingFilter def myAuthenticationFailureHandler def init = { servletContext -> authenticationProcessingFilter.authenticationFailureHandler = myAuthenticationFailureHandler } } CONFIDENTIAL 43
  • 44. Custom UserDetailsService CONFIDENTIAL 44
  • 45. Custom UserDetailsService  Very common customization  Documented in the plugin docs in section “11 Custom UserDetailsService” CONFIDENTIAL 45
  • 46. Custom UserDetailsService  General workflow: • Create a custom o.s.s.core.userdetails.UserDetailsService (o.c.g.g.p.s.GrailsUserDetailsService) implementation • Directly implement the interface (best) • or extend org.codehaus.groovy.grails.plugins.springsecurity. GormUserDetailsService (ok, but usually cleaner to implement the interface) CONFIDENTIAL 46
  • 47. Custom UserDetailsService  General workflow (cont.): • Create a custom implementation of o.s.s.core.userdetails.UserDetails • Extend org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser • or extend o.s.s.core.userdetails.User • or directly implement the interface CONFIDENTIAL 47
  • 48. Custom UserDetailsService  General workflow (cont.): • Register the bean override in grails-app/conf/spring/resources.groovy: import com.mycompany.myapp.MyUserDetailsService beans = { userDetailsService(MyUserDetailsService) } CONFIDENTIAL 48
  • 49. Custom AuthenticationProvider CONFIDENTIAL 49
  • 50. 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 CONFIDENTIAL 50
  • 51. Custom AuthenticationProvider  General workflow (cont.): • You'll probably want a custom o.s.s.core.Authentication • Extend an existing implementation, e.g. o.s.s.authentication.UsernamePasswordAuthenticationToken • or directly implement the interface CONFIDENTIAL 51
  • 52. 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 CONFIDENTIAL 52
  • 53. 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 section “10 Authentication Providers” of the docs • Register the filter in its position as described in section “16 Filters” of the docs CONFIDENTIAL 53
  • 54. Custom Post-logout Behavior CONFIDENTIAL 54
  • 55. 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 ”/”) CONFIDENTIAL 55
  • 56. 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 CONFIDENTIAL 56
  • 57. 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 CONFIDENTIAL 57
  • 58. 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 CONFIDENTIAL 58
  • 59. Custom Post-logout Behavior  To add logic to dynamically determine redirect url (cont.): private static final ThreadLocal<Authentication> AUTH_HOLDER = new ThreadLocal<Authentication>() … void onLogoutSuccess(...) throws ... { AUTH_HOLDER.set authentication try { super.handle(request, response, authentication) } finally { AUTH_HOLDER.remove() } } CONFIDENTIAL 59
  • 60. Custom Post-logout Behavior  To add logic to dynamically determine redirect url (cont.): • Override determineTargetUrl protected String determineTargetUrl(...) { Authentication auth = AUTH_HOLDER.get() String url = super.determineTargetUrl(request, response) if (auth instanceof OrganizationAuthentication) { OrganizationAuthentication authentication = auth url = ... } url } CONFIDENTIAL 60
  • 61. Custom Post-logout Behavior  To add logic to dynamically determine redirect url (cont.): • Redefine the logoutSuccessHandler bean in resources.groovy import com.mycompany.myapp.CustomLogoutSuccessHandler import o.c.g.g.plugins.springsecurity.SpringSecurityUtils beans = { def conf = SpringSecurityUtils.securityConfig logoutSuccessHandler(CustomLogoutSuccessHandler) { redirectStrategy = ref('redirectStrategy') defaultTargetUrl = conf.logout.afterLogoutUrl } } CONFIDENTIAL 61
  • 62. Customization Overview CONFIDENTIAL 62
  • 63. Customization Overview  Subclass or replace filters in the chain: • SecurityContextPersistenceFilter • MutableLogoutFilter • RequestHolderAuthenticationFilter (UsernamePasswordAuthenticationFilter) • SecurityContextHolderAwareRequestFilter • RememberMeAuthenticationFilter • AnonymousAuthenticationFilter • ExceptionTranslationFilter • FilterSecurityInterceptor CONFIDENTIAL 63
  • 64. Customization Overview (cont)  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) CONFIDENTIAL 64
  • 65. Customization Overview (cont)  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 CONFIDENTIAL 65
  • 66. See http://burtbeckwith.com/blog/?p=1090 for a blog post on the previous talk in London CONFIDENTIAL 66
  • 67. Thank you CONFIDENTIAL 67