Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I implement a custom FilterSecurityInterceptor using grails 1.3.2 and the plugin spring-security-core 1?
    primarykey
    data
    text
    <p>I'm writing a grails 1.3.2 application and implementing security with spring-security-core 1.0. For reasons outside the scope of this question, I'm implementing a custom FilterSecurityInterceptor in addition to the out of the box interceptors. I've started with a <a href="http://blogs.bytecode.com.au/glen/2010/01/15/hacking-custom-authentication-providers-with-grails-spring-security.html" rel="nofollow noreferrer">blog entry</a> on the topic and attempted to adjust it for Spring Security 3 without much success.</p> <p>Loosely following the blog (since it is based on an older version of Spring Security), I've created the following classes:</p> <ol> <li>A org.springframework.security.authentication.AbstractAuthenticationToken subclass to hold my credentials.</li> <li>A org.springframework.security.authentication.AuthenticationProvider subclass to implement the authenticate and supports methods for populating an Authentication instance with data from my UserDetailsService.</li> <li>A org.springframework.security.web.access.intercept.FilterSecurityInterceptor subclass to implement doFilter and afterPropertiesSet methods.</li> <li>Some configuration of beans and the spring-security-core plugin to recognize my AuthenticationProvider and insert my filter into the filter chain.</li> </ol> <p>My AbstractAuthenticationToken is pretty simple:</p> <pre><code>class InterchangeAuthenticationToken extends AbstractAuthenticationToken { String credentials Integer name Integer principal String getCredentials() { //necessary or I get compilation error return credentials } Integer getPrincipal() { //necessary or I get compilation error return principal } } </code></pre> <p>My AuthenticationProvider is pretty simple:</p> <pre><code>class InterchangeAuthenticationProvider implements org.springframework.security.authentication.AuthenticationProvider { Authentication authenticate(Authentication customAuth) { def authUser = AuthUser.get(customAuth.principal) if (authUser) { customAuth.setAuthorities(authUser.getAuthorities()) customAuth.setAuthenticated(true) return customAuth } else { return null } } boolean supports(Class authentication) { return InterchangeAuthenticationToken.class.isAssignableFrom(authentication) } } </code></pre> <p>I've implemented a trivial FilterSecurityInterceptor. Eventually this will do something interesting:</p> <pre><code>class InterchangeFilterSecurityInterceptor extends FilterSecurityInterceptor implements InitializingBean { def authenticationManager def interchangeAuthenticationProvider def securityMetadataSource void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { if (SecurityContextHolder.getContext().getAuthentication() == null) { def myAuth = new InterchangeAuthenticationToken() myAuth.setName(1680892) myAuth.setCredentials('SDYLWUYa:nobody::27858cff') myAuth.setPrincipal(1680892) myAuth = authenticationManager.authenticate(myAuth); if (myAuth) { println "Successfully Authenticated ${userId} in object ${myAuth}" // Store to SecurityContextHolder SecurityContextHolder.getContext().setAuthentication(myAuth); } } chain.doFilter(request, response) } void afterPropertiesSet() { def providers = authenticationManager.providers providers.add(interchangeAuthenticationProvider) authenticationManager.providers = providers } } </code></pre> <p>Finally I configure some beans:</p> <pre><code>beans = { interchangeAuthenticationProvider(com.bc.commerce.core.InterchangeAuthenticationProvider) { } interchangeFilterSecurityInterceptor(com.bc.commerce.core.InterchangeFilterSecurityInterceptor) { authenticationManager = ref('authenticationManager') interchangeAuthenticationProvider = ref('interchangeAuthenticationProvider') securityMetadataSource = ref('objectDefinitionSource') } } </code></pre> <p>And do some configuration of the plugin:</p> <pre><code>grails.plugins.springsecurity.dao.hideUserNotFoundExceptions = true //not setting this causes exception grails.plugins.springsecurity.providerNames = [ 'interchangeAuthenticationProvider', 'daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider' ] </code></pre> <p>And set the filter order in Bootstrap.groovy:</p> <pre><code>def init = {servletContext -&gt; //insert our custom filter just after the filter security interceptor SpringSecurityUtils.clientRegisterFilter('interchangeFilterSecurityInterceptor', SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order + 10) &lt;snip /&gt; } </code></pre> <p>When I hit a URL, I get the following exception which stumps me:</p> <pre><code>2010-07-30 15:07:16,763 [http-8080-1] ERROR [/community-services].[default] - Servlet.service() for servlet default threw exception java.lang.NullPointerException at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:171) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:106) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) at org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:40) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter.doFilterInternal(GrailsReloadServletFilter.java:104) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:67) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:66) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) at java.lang.Thread.run(Thread.java:637) </code></pre> <p>So where am I messing up, or did I make this too complex and I missed something simple?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload