We are developing our project in grails. And we want to show data to user according to the country from where they are accessing our website.
I have a field where I store the country location. By using geoip grails plugin.
My question is can we initialize the session with the country name from where the site is being excessed before it hits any controller/action, let say in some config file or somewhere else.
You should be able to do it in a Filter. Something like this, placed in grails-app/conf as GeoFilters.groovy:
class GeoFilters {
def geoIpService
def filters = {
countryCheck(controller:'*', action:'*') {
before = {
if( !session.geolocation ) {
session.geolocation = geoIpService.getLocation( request.remoteAddr )
}
}
}
}
}
Should (I haven't tried it though) check to see if geolocation exists in the session, and if it doesn't, it should fetch it from the geoIpService.
Related
I have a grails application in which I am using shiro plugin to add security. I do not give access to any of the urls without login to any user. All goes fine. Now I want to find whether there is any way to allow access to some of the urls without login ? Some links should be working without login.
that's easy. If you've a standard shiro setup, you'll find a ShiroSecurityFilters.groovy in your projects conf-folder which looks something like this:
class SecurityFilters {
def filters = {
all(uri: "/**") {
before = {
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
accessControl()
}
}
}
}
just replace it with something like this:
class SecurityFilters {
def filters = {
all(uri: "/**") {
before = {
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
if ((controllerName+':'+actionName) in ['book:view', 'book:list']) {
return true
} else {
accessControl()
}
}
}
}
}
This will make the two actions list and view of the bookController accessible to everyone.
Hope that helps...
I need to log any action made by users in sfDoctrineGuard plugin. Basically I'll need to log:
module/action
date
IP from where users are accessing the application
Any plugin? Is that possible? How?
This could be probably the plugin you need, sfDoctrineGuardLoginHistoryPlugin and allows to extend the information that you save.
Check for more plugins here.
Take a look at the code of the plugin, you just need to change the following file: PluginUserLoginHistoryTable.class.php
Add in the function writeLoginHistory and createHistoryEntry the information you want:
writeLoginHistory(sfEvent $event) {
//... same code than in the plugin
//lets save module and action
if (!isset($request) )
{
$sActionName = sfContext::getInstance()->getActionName();
$sModuleName = sfContext::getInstance()->getModuleName();
}
else
{
if (isset($request["module"]))
{
$sActionName = $request["action"];
$sModuleName = $request["module"];
}
}
//get values from the http bar URL
if (!isset($sModuleName))
{
$sFullURL = sfContext::getInstance()->getRouting()->getCurrentInternalUri();
///... strip action and module name from the above URL
}
}
Remember to pass those values to createHistoryEntry function and also to update that function with more input values to be saved.
I'm trying to apply annotation-based security to my Grails app.
Peter says here that we should be using Shiro's annotations instead of the quasi-deprecated grails-shiro plugin annotations.
How does one get that working?
I'm finding the grails-shiro plugin strays from how Shiro does things, what with the Realm-converting and all. Has anyone tried implementing Shiro directly rather than using the grails plugin? Any success?
Thanks,
Graham.
G'day I have taken over the Grails-Shiro plugin project. I'm currently re-writing the functional tests and can confirm that the shiro annotations do work, with a couple of caveats:
You can use them in controllers on method actions in grails 2.x
You can use them on Service methods
They don't currently work on service classes (I'm investigating this)
e.g. this works on a service
class SecuredMethodsService {
def methodOne() {
return 'one'
}
#RequiresGuest
def methodTwo() {
return 'two'
}
#RequiresUser
def methodThree() {
return 'three'
}
#RequiresAuthentication
def methodFour() {
return 'four'
}
#RequiresRoles('User')
def methodFive() {
return 'five'
}
#RequiresPermissions("book:view")
def methodSix() {
return 'six'
}
}
or in a controller on an action method like this:
#RequiresAuthentication
def unrestricted() {
render(view: 'simple', model: [msg: "secure action"])
}
When using annotations you may need to add an "afterView" filter to catch the AuthorizationException thrown by the annotation e.g.
class ShiroSecurityFilters {
def filters = {
all(uri: "/**") {
before = {
// Ignore direct views (e.g. the default main index page).
if (!controllerName) return true
// Access control by convention.
accessControl()
}
afterView = { e ->
while (e && !(e instanceof AuthorizationException)) {
e = e.cause
}
if (e instanceof AuthorizationException) {
if (e instanceof UnauthenticatedException) {
// User is not authenticated, so redirect to the login page.
flash.message = "You need to be logged in to continue."
redirect(
controller: 'auth',
action: 'login',
params: [targetUri: request.forwardURI - request.contextPath])
} else {
redirect(controller: 'auth', action: 'unauthorized')
}
}
}
}
}
}
I hope that helps. A new version of the plugin should be released RSN.
Cheers,
Peter.
Since nobody is anwering...
I don't know how you get the annotations to work, but I've used shiro in several Grails projects and didn't miss them... So why do you need them?
When you need to permission explicit roles, you can just create some ShiroRoles and assign star-permissions to them: 'book:*' allows a role to execute all actions on the book controller. 'book:list,show' allows a role to only list or show books.
When you need implicit permissions, use a filter. So if you want to give someone access if she is (for instance) the boss of someone, just fetch the object on which you want to decide in a filter and make a decision.
When you need switches in you gsp-code (e.g. show this only if it's an admin), use the shiro tags. Just unzip the shiro plugin and look for the taglibrary. It is well documented.
HTH
I am building a Grails application which uses the Spring Security Core Plugin.
I have two applications roles. ROLE_USER and ROLE_ADMIN
Users can upload files which are stored in a directory called files
External users should not see any file
ROLE_ADMIN users can see every uploaded file.
ROLE_USER user should be allowed only in certain cases
A file url request should look like this
http://localhost:8080/MyApp/files/patient1-1.png
For the first case I have set in conf/Config.groovy the next url interceptor
grails.plugins.springsecurity.interceptUrlMap = [
'/files/**': ['ROLE_USER']
]
For the second and third case I created the next file conf/MyFilters
class MyFilters {
def springSecurityService
public currentUser() { return User.get(springSecurityService.principal.id);}
public userRoles() { return springSecurityService.principal.authorities*.authority }
def filters = {
fileFilter(uri: '/files/*') {
before = {
println "Here"
def String url = request.getRequestURL()
if(url.contains("files/patient")) {
if(!userRoles().contains(Role.ROLE_ADMIN)) {
if(PLAIN ROLE USER IS NOT ALLOWED) {
redirect(action:'login')
return false;
}
}
}
}
after = {
}
afterView = {
}
}
}
}
However, it does not seem to get triggered. I never see the Here print out.
Any idea what am I doing wrong?
You shouldn't mix Grails filters with Spring Security - everything is doable from Spring Security. Are you using the "InterceptUrlMap" config type (grails.plugins.springsecurity.securityConfigType = "InterceptUrlMap")? By default it uses annotations, so the securityConfigType setting would be ignored.
If you're using annotations you can add this url pattern to the staticRules config option:
grails.plugins.springsecurity.controllerAnnotations.staticRules = [
'/files/**': ['ROLE_USER']
]
Try running grails clean to force a full compile; it might be a simple as some code being out of sync.
I'm using grails and facebook graph plugin for the user registration. However, instead of checking facebook session in every action and controller. Is there a better way to check the session before entering controller? So, I don't have to duplicate the code to check authentication.
class FacebookSecurityFilters {
def filters = {
all(controller:'*', action:'*') {
before = {
println "test"
}
after = {
}
afterView = {
}
}
}
}
I created this filter by using command grails create-filters . But it's not fired at all, I mean it didn't print "test" at all. Do I need to register the filter? I'm using Grails1.4M01
Thanks
Use a filter - it's a great way to intercept all actions, or a subset of actions based on a pattern: http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.6%20Filters