Grails中的访问控制、角色和权限

3

我第一次在Grails应用程序上工作,现在我想保护一些页面只能由管理员查看,并为其他用户授予一些权限。

我正在使用Grails的Apache Shiro插件。

我的引导样本代码如下:

class BootStrap {

def init = { servletContext ->
    def adminRole

    if(ShiroRole.findByName("Admin".isEmpty())){
        adminRole = new ShiroRole(name: "Administrator")
        adminRole.addToPermissions("*:*")
        adminRole.addToPermissions("admin")

        adminRole.save()

// 'user'现在拥有所有管理员权限 }

    if (ShiroUser.findAllByUsername("user").isEmpty()) {
        def user = new ShiroUser(username: "user", passwordHash: new Sha256Hash("pass").toHex())
        user.addToPermissions("*:*")
        user.addToRoles(adminRole)

        user.save()

    }

    if (ShiroUser.findAllByUsername("Guest").isEmpty()) {
        def user = new ShiroUser(username: "Guest", passwordHash: new Sha256Hash("pass").toHex())
        user.addToPermissions("inventory:*")
        user.save()
    }


}
def destroy = {
}

我的ShiroSecurityFilters如下:

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()

        }
    }
}

我希望让“Guest”只能访问库存脚手架。然而,在我的应用程序中,一旦用户“Guest”登录,就能够访问其他控制器,但我不希望发生这种情况。感谢您的帮助。

如果有更好的使用Shiro角色、访问控制和/或权限的方法,请告诉我。

谢谢

1个回答

3
好的,让我们看看...
开头就有一个错别字:

"Admin".isEmpty()

将永远为false...我猜您没有定义角色“false”...

而您正在寻找“管理员”,但创建的是“管理者”...

执行一个

adminRole.save(flush:true, failOnError:true)

使用adminRole.saveAndFlush()而不是adminRole.save()。这将确保对象被真正保存。

角色Administrator已经拥有所有权限("*:*"),而"admin"不是典型的shiro权限,因此您可以删除此行代码(adminRole.addToPermissions("admin"))。

如果您执行

user.addToRoles(adminRole)

您不需要添加"*:*"的权限。角色已经足够了。

我现在创建了一个测试项目,安装了shiro,做了create-auth-controllercreate-wildcard-realmcreate-filters ShiroSecurity

通过在Config.groovy中添加以下两行内容,激活BootStrap和Shiro-Realm的日志记录:

debug   'grails.app.conf.BootStrap'
debug   'grails.app.realm'

这是我的BootStrap.groovy文件(有趣的部分):
def init = { servletContext ->
    def adminRole

    if(ShiroRole.findByName("Administrator")==null){
        adminRole = new ShiroRole(name: "Administrator")
        adminRole.addToPermissions("*:*")
        adminRole.save(flush:true, failOnError:true)
        log.debug adminRole.dump()
    }
    println ShiroUser.findAllByUsername("user").dump()
    log.debug "="*80
    if (ShiroUser.findAllByUsername("user").isEmpty()) {
        def user = new ShiroUser(username: "user", passwordHash: new Sha256Hash("pass").toHex())
        user.addToRoles(adminRole)
        user.save(flush:true, failOnError:true)
        log.debug user.dump()
    }

    if (ShiroUser.findAllByUsername("Guest").isEmpty()) {
        def user = new ShiroUser(username: "Guest", passwordHash: new Sha256Hash("pass").toHex())
        user.addToPermissions("inventory:*")
        user.save(flush:true, failOnError:true)
        log.debug user.dump()
    }

}

我的ShiroSecurityFilters.groovy文件内容如下:

def filters = {
    all(controller:'*', action:'*') {
        before = {
        // Ignore direct views (e.g. the default main index page).
        if (!controllerName) return true

        // Access control by convention.
        accessControl()

        }
    }
}

你可以看到,我的SecurityFilters是基于控制器和操作的...只是我的个人喜好...

但我想你的问题只是基于错误的引导。当你使用shiro时,日志记录非常有用...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接