I am (finally) upgrading my Acegi plugin to Spring Security Core. At the same time, I am upgrading from Grails 1.3.7 to 2.0. My site was fully functional before, but now when I try to get to my default page (which is IS_AUTHENTICATED_ANONYMOUSLY) I am redirected to the auth action of my LoginController. This method was never invoked with Acegi, so I don't know what the problem is. Have I set up my configuration wrong or is there something else I need to be thinking about?
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.InterceptUrlMap
grails.plugins.springsecurity.interceptUrlMap = [
'/blog/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/static/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/consensus/**':['IS_AUTHENTICATED_FULLY'],
'/login/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/signup/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/home/**':['IS_AUTHENTICATED_FULLY'],
'/test/**':['ROLE_ADMIN'],
'/admin/**':['ROLE_ADMIN'],
'/adminmanage/**':['ROLE_ADMIN'],
'/quartz/**':['ROLE_ADMIN'],
'/**/*.css':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/js/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/images/**':['IS_AUTHENTICATED_ANONYMOUSLY'],
'/monitoring**':['ROLE_ADMIN'],
'/**':['IS_AUTHENTICATED_FULLY']
]
My UrlMappings.groovy is:
class UrlMappings {
static mappings = {
"/"(controller:"x", action:"y")
"/z/?"(controller:"x", action:"y")
"/$controller/$action?/$id?"
{
constraints {
// apply constraints here
}
}
"500"(view: '/error')
}
}
I have been reading through the documentation but am having some problems, so I am not sure if there is more relevant code one would need to see. If there is, please let me know and I will add it. Thanks.
Other options in my Config.groovy were incorrect and this caused the problem. Once I corrected them everything worked fine.
Despite it being called out in the documentation, I had security fields that were not prepended with grails.plugins.springsecurity This caused the engine not to recognize them, which for some reason resulted in the call to auth.
After remove openid plugin all requests redirects me to the login page! I don't know what to do... I've already remove everything related.
Related
Upgrading to grails 4, sessionRegistry.getAllPrincipal() is always empty.
The original spring bean in resources.groovy were
sessionRegistry(SessionRegistryImpl)
concurrentSessionFilter(ConcurrentSessionFilter){
sessionRegistry = sessionRegistry
expiredUrl = '/login'
}
As this was no longer working I tried updating resources.groovy to
sessionRegistry(SessionRegistryImpl)
registerSessionAuthenticationStrategy(RegisterSessionAuthenticationStrategy, ref(sessionRegistry))
sessionFixationProtectionStrategy(SessionFixationProtectionStrategy)
concurrentSessionControlAuthenticationStrategy(ConcurrentSessionControlAuthenticationStrategy, ref(sessionRegistry)){
maximumSessions=1
exceptionIfMaximumExceeded=true
}
compositeSessionAuthenticationStrategy(CompositeSessionAuthenticationStrategy,
[ref(registerSessionAuthenticationStrategy),ref(sessionFixationProtectionStrategy),ref(concurrentSessionControlAuthenticationStrategy)])
All of those beans are from the org.springframework.security.web.authentication.session package.
I've added names to grails.plugin.springsecurity.providerNames as well
The DaoAuthenticationProvider is extended by a custom auth provider. Login and logout works fine, but the principals never get registered in the upgraded app. Do I need register them manually (sessionRegistry.registerNewSession())?
There are old answers that say to use grails install-templates and then edit the web.xml in src/templates/war. However in grails 4, install-templates didn't generate war/web.xml
I tried adding it a /WEB-INF/web.xml, but still no luck.
I think you're missing the sessionAuthenticationStragegy bean definition, try removing the compositeSessionAuthenticationStrategy line and replace it with:
sessionAuthenticationStrategy(CompositeSessionAuthenticationStrategy, [ref('concurrentSessionControlAuthenticationStrategy'), ref('sessionFixationProtectionStrategy'), ref('registerSessionAuthenticationStrategy')])
This is the only difference I see between your code and mine, which is working with Grails 4.
I'm getting ready to implement the Spring Security UI plugin (we've already implemented the Spring Security Core plugin). I know the core plugin has support for users, roles, and groups, however, I don't see any mention of groups in the Spring Security UI plugin's documentation. Does Spring Security UI plugin not support creating, edition, etc. groups? Anyone tried adding this functionality?
A late response, but I had the same question so I thought I would just try it.
I have just attempted this myself and I believe the the answer is No. (out of the box)
The spring security ui plugin doesn't take the groups into consideration. If you try to edit a user
myapp/user/edit/1
you will recieve some sort of error like:
Class groovy.lang.MissingPropertyException
Message
No such property: authority for class: com.myapp.security.SecGroup Possible solutions: authorities
I'm curious if you found a way around this? Or we will have to customize the the plugin.
As Julian noted the UI doesn't provide support for groups out of the box. To avoid the error you can do the following (customize the plugin):
Copy the User controller into your project to override the plugin's controller:
grails s2ui-override user <your-package-for-controller>
Copy the "buildUserModel" from the plugin code in UserController and edit the userRoleNames field:
import grails.plugin.springsecurity.SpringSecurityUtils
class UserController extends grails.plugin.springsecurity.ui.UserController {
protected Map buildUserModel(user) {
...
// Added so that when using groups doesn't cause an error
Set userRoleNames
if (SpringSecurityUtils.securityConfig.useRoleGroups) {
String groupAuthorityFieldName = SpringSecurityUtils.securityConfig.authority.groupAuthorityNameField
userRoleNames = user[authoritiesPropertyName].collect { it[groupAuthorityFieldName].collect { it[authorityFieldName] } }
} else {
userRoleNames = user[authoritiesPropertyName].collect { it[authorityFieldName] }
}
...
}
I'm running my app in development environment.
Using this simple controller:
class MyController {
def index() {
redirect uri: '/'
}
}
I'm getting redirected to http://localhost:8080/[:]/ location for some reason.
$appName seems good inside Config.groovy. grails.serverURL looks also OK.
What's the problem?
UPDATE 1
I'm using grails 2.2.4
UPDATE 2
The problem is with invalid grails.serverURL value. When I'm debugging the app, it has a correct value inside Config.groovy. When I'm printing out this value from servlet method it's set to http://localhost:8080/[:]/ for some reason. I'm using Spring Security Core 1.2.7.3 and Spring Security UI 0.2, I think that for some reason grails.serverURL is overwritted inside this plugin.
How to fix it?
The answer was simple. I've included MyConfig.groovy inside Config.groovy like this:
grails.config.locations = [ "classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
MyConfig,
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy"]
there was also environments.production, environments.development and environments.test sections however, $appName is undefined there. I've removed setting of grails.serverURL from MyConfig.groovy and its worked now.
I am trying to write a grails plugin using Spring social core plugin. I get the provider popup and after I enter user and password it is giving me 404. As I debugged the code, it is coming into SpringSocialProviderSignInController handleSignIn() method and it is not getting anything for signup url. In grails plugin this is the code snipet
if (userIds.size() == 0) {
if (log.isDebugEnabled()) {
log.debug("No user found in the repository, creating a new one...")
}
ProviderSignInAttempt signInAttempt = new ProviderSignInAttempt(connection, connectionFactoryLocator, usersConnectionRepository)
request.setAttribute(ProviderSignInAttempt.SESSION_ATTRIBUTE, signInAttempt, RequestAttributes.SCOPE_SESSION)
//TODO: Document this setting
result = request.session.ss_oauth_redirect_on_signIn_attempt ?: config.page.handleSignIn
}
I see that even in the regular spring social web jar this has similar logic. Except in the web there is a default set on signupUrl. I tried giving the same value(/signup) in config.page.handleSignIn but it did not help.
if (userIds.size() == 0) {
ProviderSignInAttempt signInAttempt = new ProviderSignInAttempt(connection, connectionFactoryLocator, usersConnectionRepository);
request.setAttribute(ProviderSignInAttempt.SESSION_ATTRIBUTE, signInAttempt, RequestAttributes.SCOPE_SESSION);
return redirect(signUpUrl);
}
In general, I am trying to understand what this signUpUrl does. I am not able to go further after this. Is it mandatory to give signUpUrl? My understanding was no.
Have asked the same question in spring social forum, but is not getting any response there. Trying my luck here.
Found meaningful answer in spring forum : Spring Forum Link
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'.
If anyone's interested - I found some workarounds for this issue:
1. Ask SiteMinder admin to add SM_USER header to all images or to some set of them limited to url location. This is disabled by default due to general performance. Then loose all additional filters and live happily ever after with preAuth one.
2. Use static content instead of including images in .war and redirect :]
HOW TO:
Put all needed images in var/www/yourfolder/images
Add some aliases to your httpd config :
Alias /yourapp/imgs var/www/yourfolder/images
ProxyPass /yourapp/imgs !
Restart your service
Be happy using images :D
I am aware that this is not the solution but only workaround. Yet it works.
I will be still happy to hear some better ideas :)
Cheers.