How to change Grails Spring Security Cookie Path - grails

I've got two grails applications using spring security:
Core
Module (user and role tables mapping to Core db tables)
I want to have a single sign on functionality using "remember me". The problem is that the cookies are stored in different paths "/Core" and "/Module" which I'm guessing is the reason why it isn't working.
Does anyone know how to change the cookie path to be "/"?
Notes:
Do I need to make a change in Spring Security or the Tomcat server configuration (using intellij)
I want to avoid setting up a CAS server if possible
I'm looking into plugins as an alternative
Thanks any help would be greatly appreciated

When the remember-me filter creates the remember-me cookie, it sets the cookie path to the context path obtained from the request object (see related source code here). If you want to customize this behavior, you'll need to override the setCookie() and cancelCookie() methods of the remember-me service implementation your application uses (either TokenBasedRememberMeServices or PersistentTokenBasedRememberMeServices) in a subclass, and configure the RememberMeAuthenticationFilter to use your custom implementation.

Here's how I impltemented it.
create a new service with extends TokenBasedRememberMeServices
override setCookie and cancelCookie method to set cookie path.
Add cookiePath variable and add method to setCookepath()
Update resources.groovy
rememberMeServices(YourTokenBasedRememberMeServices) {
userDetailsService = ref("userDetailsService")
key = conf.rememberMe.key
cookieName = conf.rememberMe.cookieName
alwaysRemember = conf.rememberMe.alwaysRemember
tokenValiditySeconds = conf.rememberMe.tokenValiditySeconds
cookiePath = some config variable
}

Related

spring security: what's the best practice for include value in permission?

In spring security, or RBAC, the Authority is described as a string, such as "download-file" means user can download file. If I need to limit user maximum daily download times and assign different values to different user, means the Authority contains dynamic values, how can I do this in spring security?
As you are alluding to there is a difference between authorities (i.e. roles) and permissions. Authorities tend to broadly apply for an application and have no state while permissions tend to be on specific objects and contain state.
This seems more like a domain problem than a permissions problem. Putting the logic into security feels a bit like having a form that must contain a valid email and checking the email format in security. I'd consider moving the logic outside of the security code.
If you really want to do this with Spring Security, I'd use a custom Bean that performs the check:
#Component
public class Download {
public boolean isAlowedForUser(Authentication authentication) {
// ...
return result;
}
public boolean isAllowedForCurrentUser() {
return isAllowedForUser(SecurityContextHolder.getContext().getAuthentiation());
}
}
Then you can autowire the Bean into your code and check the permission by invoking the code. If you prefer, you can also integrate into Spring Security's method security to perform the checks. To enable it you need to specify #EnableGlobalMethodSecurity(prePostEnabled = true) at the top of one of your configuration classes. Then you can use something like this on a Spring managed Bean:
#PreAuthorize("#download.isAllowedForCurrentUser()")
public void downloadFile(String fileName) {
Please refer this link
Spring Boot : Custom Role - Permission Authorization using SpEL
You can add new permission , like "DOWNLOAD_FILE" and authenticate if the current user has that permission using -
#PreAuthorize("hasPermission('DOWNLOAD_FILE')")
You can also limit access for Roles as well
#PreAuthorize("hasRole('ADMIN') and hasPermission('DOWNLOAD_FILE')")

secure grails spring security controllers

I am using spring security plugin in my Grails project. In order to secure the URLs, I am using interceptUrlMap.
My User and Role classes are User.groovy and Role.groovy respectively. Based on these classes, the s2-quickstart script has generated the UserController.groovy and RoleController.groovy
The problem arises when I want to secure UserController.groovy. My requirement is that I cannot permit all users to create a new user. Therefore certain actions of the UserController need to be blocked for users with the proper role privileges.
However no matter how I try to restrict access, I see that all the actions of UserController are always accessible.
Could anyone please explain where I am going wrong. Any help is highly appreciated.
Better use annotations instead of defining rules in Config.groovy. That helps in two ways i.e. first, hot reloading will always work and second you can override any rule easily in Config.groovy. That means you can use both annotation and plain rules in Config.groovy.
So change this in Config.groovy
grails.plugin.springsecurity.securityConfigType = "Annotation"
and start protecting your controller or actions like:
import grails.plugin.springsecurity.annotation.Secured
#Secured(["ROLE_MRU"])
class UserController {
def edit() {
// action code
}
#Secured(["ROLE_ADMIN"])
def show() {
// action code
}
}
I have managed to solve the issue. The problem was that I was editing Config.groovy while the application was still running. Hot deployment was not taking place.
Once I restarted the application, the functionality started working.
Thanks for all the help.

Checking whether the user authenticated using spring security inside a filter

I'm trying to do this in my groovy class which is in src directory of my grails application.
Its an Filter. The class looks like this :
class Proxy implements Filter {
}
Inside the init method I'm getting the springSecurityService bean using :
GrailsApplication application = org.codehaus.groovy.grails.commons.ApplicationHolder.getApplication()
springSecurityService = application.getMainContext().getBean("springSecurityService")
And inside my doFilter I'm trying to find whether the user is been authenticated or not. I tried:
springSecurityService.isLoggedIn()
but its always returning false.
Where I'm making the mistake?
Thanks in advance.
Is it possible the order of your filters are incorrect? Your custom Filter would need to be invoked after the Spring Security Filter. If you perform new Exception().printStackTrace() inside your filter, do you see the SecurityContextPersistenceFilter in the stack? If not, then you need to change your Filter (Proxy) to be after the springSecurityFilterChain.
Try to use SecurityContextHolder
SecurityContextHolder.getContext().getAuthentication()
(but this is Java; I'm sure there is something similar you can find)

what's the best way to check user's current authority in spring3 controller methods?

User's authority is frequently changed in my web service.
In this case, how do I check user's authority effectively?
I wrote code that check user's authority in every controller temporarily.
But I think this way would not good for maintenance.
How do I check user's authority without writing checking method in every controller?
Not sure what you are doing - Spring Security automatically keeps track of authorities in the User's security context. If you need to programmatically check for some other reason, then implement the HandlerInterceptor interface, and in the preHandle method, call SecurityContextHolder.getContext().getAuthentication() to get the current user. You can then check the User's authorities.
The interceptor would be configured as follows:
<mvc:interceptors>
<bean class="com.my.package.MyInterceptor" />
</mvc:interceptors>
Add an intercept-url element to your config with the role that is required, eg.
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_FOO" />
</http>
Use HandlerMethodArgumentResolver to let Spring inject GrantedAuthority in the controller method. If a user can have more than one authority then you will need to create a class to hold user's authorities (can be named as GrantedAuthorities). After you are done, your controller method will look something like this:
#RequestMapping({"/xyz"})
public String handleXYZRequest(GrantedAuthorities authorities) {
/* use authorities if not null */
...
}
In resolver, you will use the same code that your are currently using to get authorities and it will return either null or GrantedAuthorities object. If you are using older version of Spring then use WebArgumentResolver and register it with AnnotationMethodHandlerAdapter.
Above approach avoids duplication of code and it can be used to inject anything you need from SecurityContextHolder in controller methods.
Edit
This is similar to the approach used by greenhouse. Please see WebConfig, where principal (which is Account object) is injected in controller through argument resolver.

Grails spring security core, how to set principal manually

Hi im trying to make facebook's login in a grails app, the problem I have is that when the user is logged in facebook, spring security core doesn't recognize him, how can I set the user's principal manually?
I can look for the user object but i don't know how to set it in order to get a true user when i call getAuthenticatedUser() (now it returns a null object)
Thanks in advance,
Regards
Cannot say anything regarding facebook, but Spring Security has a SecurityContextHolder that can be used to manipulate the authentication (and therefore the principal) like this:
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
....
def securityContext = SCH.context
def principal = <whatever you use as principal>
def credentials = <...>
securityContext.authentication = new PreAuthenticatedAuthenticationToken(principal, credentials)
Maybe you'll need to use a different implementation of the Authentication interface as the one used in the example.

Resources