I am trying to secure my grails application with spring security basing on preAuth by Siteminder. That's basically all I need. The application is used just for checking some stuff so no need for database.
I am stuck on some filter problems that I'm somehow unable to embrace.
At first I used only RequestHeaderAuthenticationFilter and custom UserDetails and UserDetailsService.
My spring beans:
beans = {
userDetailsService(MyUserDetailsService)
userDetailsServiceWrapper(UserDetailsByNameServiceWrapper) {
userDetailsService = ref('userDetailsService')
}
preauthAuthProvider(PreAuthenticatedAuthenticationProvider) {
preAuthenticatedUserDetailsService = ref('userDetailsServiceWrapper')
}
requestHeaderAuthenticationFilter(RequestHeaderAuthenticationFilter){
principalRequestHeader='SM_USER'
authenticationManager = ref('authenticationManager')
}
}
I have my MyUserDetailsProvider:
class MyUserDetailsService implements GrailsUserDetailsService {
MyUserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
//some super secret code here ;)
return new MyUserDetails(some needed params)
}
}
I also configured secured URLs like in every wise tutorial:
grails.plugins.springsecurity.interceptUrlMap = [
'/user/**':['ROLE_MINE'],
'/activation/**':['ROLE_SOMEOTHER, ROLE_MINE'],
'/js/**': ['IS_AUTHENTICATED_ANONYMOUSLY'],
'/css/**': ['IS_AUTHENTICATED_ANONYMOUSLY'],
'/images/**': ['IS_AUTHENTICATED_ANONYMOUSLY'],
'/*': ['IS_AUTHENTICATED_ANONYMOUSLY']
]
and some providers (left anonymous as advised in some tutorial):
grails.plugins.springsecurity.providerNames = ['preauthAuthProvider','anonymousAuthenticationProvider']
It was working great for data access but it was not allowing to load resources, images in particular. The error said that SM_USER header was not found in request.
So I thought that I can use some solution like 'filters: none' or 'security: none' so that spring would know what url request let without checking for SM_USER.
I tried adding stuff to filter and filterChain:
grails.plugins.springsecurity.filterNames = ['requestHeaderAuthenticationFilter']
grails.plugins.springsecurity.filterChain.chainMap = [
'/user/**': 'requestHeaderAuthenticationFilter',
'/activation/**': 'requestHeaderAuthenticationFilter',
'/*': 'requestHeaderAuthenticationFilter'
]
but it didn't help.
Then I tried using some other filter to be used on the resources without SM_USER header. From reference I understood that Anonymous filter might be enough.
So I made some changes:
grails.plugins.springsecurity.providerNames = ['preauthAuthProvider','anonymousAuthenticationProvider']
grails.plugins.springsecurity.filterNames = ['anonymousAuthenticationFilter','requestHeaderAuthenticationFilter']
grails.plugins.springsecurity.filterChain.filterNames = ['anonymousAuthenticationFilter','requestHeaderAuthenticationFilter'
]
grails.plugins.springsecurity.filterChain.chainMap = [
'/user/**': 'requestHeaderAuthenticationFilter',
'/versionone/**': 'requestHeaderAuthenticationFilter',
'/activation/**': 'requestHeaderAuthenticationFilter',
'/js/**': 'anonymousAuthenticationFilter',
'/css/**': 'anonymousAuthenticationFilter',
'/images/**': 'anonymousAuthenticationFilter',
'/*': 'requestHeaderAuthenticationFilter'
]
YAY that helped for images. But another problem started to occur.
Instead of myUserDetails object that should be returned when auth is correct I am obtaining some String object quite frequently. And my app is failing on inability to find one property in this String object (which is quite obvious as it's not there ;))
Does anyone know how to deal with that problem? Resigning from showing images is not an option ;)
Is there some way to exclude images/other resources from filterchain in spring security grails configuration...? Just like it was done in normal Java .xml way...?
I will appreciate all the help and suggestions how to solve this.
Thanks !!!
//EDIT: if by any chance anyone's using this as a reference to set up security for siteminder sso please note to add :
checkForPrincipalChanges = 'true'
invalidateSessionOnPrincipalChange = 'true'
properties to your requestHeaderAuthenticationFilter. Otherwise you will be dealing with not updated Authority in http session when calling springSecurityService.getPrincipal() hence users might be 'logged in as someone else'. :) Also consider changing scope of your beans to 'prototype'.