I am trying to protect a grails application using spring security based on preAuth from Siteminder. That is basically all I need. The application is used only to check some things, so there is no need for a database.
I am stuck with some filter issues that I cannot accept anyway.
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 MyUserDetailsProvider:
class MyUserDetailsService implements GrailsUserDetailsService { MyUserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
I also set up secure URLs, as 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 (anonymously anonymous, as indicated in some tutorials):
grails.plugins.springsecurity.providerNames = ['preauthAuthProvider','anonymousAuthenticationProvider']
It worked great for accessing data, but did not allow loading resources, in particular images. The error indicated that the SM_USER header was not found in the request.
So I thought that I could use some kind of solution, such as "filters: none" or "security: none", so that spring knows that the url request allows without checking SM_USER.
I tried adding material for filtering and filterChain:
grails.plugins.springsecurity.filterNames = ['requestHeaderAuthenticationFilter'] grails.plugins.springsecurity.filterChain.chainMap = [ '/user/**': 'requestHeaderAuthenticationFilter', '/activation/**': 'requestHeaderAuthenticationFilter', '/*': 'requestHeaderAuthenticationFilter' ]
but it did not help.
Then I tried to use some other filter that would be used on resources without the SM_USER header. From the help, I realized that an 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 who helped the images. But another problem arose.
Instead of the myUserDetails object, which should be returned with proper authorization, I pretty often get some String object. And my application fails in the inability to find one property in this String object (which is quite obvious since it does not exist;))
Does anyone know how to deal with this problem? Refusal to display images is not an option;)
Is there any way to exclude images / other resources from filterchain in grails spring ... security configuration? Just as it was done in the usual Java.xml path ...?
I would be grateful for all the help and suggestions on how to solve this.
Thanks!!!
// EDIT: if anyone using this as a security setting link for siteminder sso, note to add:
checkForPrincipalChanges = 'true' invalidateSessionOnPrincipalChange = 'true'
in your requestHeaderAuthenticationFilter. Otherwise, you will be dealing with a non-updated privilege in the http session when you call the springSecurityService.getPrincipal () function, so users can be "registered as someone else." :) Also consider changing the scope of your beans to 'prototype'.