This was a tricky problem I’ve been trying to solve for a little while.
If your webserver is providing the authentication service then your application simply needs to read in the `remoteUser` value out of the request header and trust it. In Grails you can do this with the Spring Security Core plugin using a PreAuthenticatedAuthenticationProvider. But it requires some configuration.
Follow the regular Spring Security Core setup process with the following adjustments.
In Config.groovy, define the providers you want available:
grails.plugins.springsecurity.providerNames = ['preAuthenticatedAuthenticationProvider', 'anonymousAuthenticationProvider']
And we need to define that preAuthenticated provider as a bean.
In resources.groovy we need:
beans = {
userDetailsService(org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService) {
grailsApplication = ref('grailsApplication')
}
userDetailsByNameServiceWrapper(org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper) {
userDetailsService = ref('userDetailsService')
}
preAuthenticatedAuthenticationProvider(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider) {
preAuthenticatedUserDetailsService = userDetailsByNameServiceWrapper
}
requestHeaderAuthenticationFilter(org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter) {
principalRequestHeader = 'remoteUser'
authenticationManager = ref('authenticationManager')
}
}
And finally, in our BootStrap.groovy file we need to register the authentication filter:
import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
class BootStrap {
def init = { servletContext ->
SpringSecurityUtils.clientRegisterFilter('requestHeaderAuthenticationFilter', SecurityFilterPosition.PRE_AUTH_FILTER)
}
}