20130115-使用Grails Shiro Plugin实现身份验证01

来源:互联网 发布:ip网络广播系统破解版 编辑:程序博客网 时间:2024/06/05 04:31

目标

  • 尽可能简单的使用Grails Shiro Plugin实现身份验证功能.

安装

  • Grails版本:2.1.1
  • 约定:在代码示例中,任何使用$开头,说明这是一个shell命令
1 $ grails create-app shiro-example2 $ cd shiro-example
  • shiro plugin最新的插件版本是1.1.4,可以使用grails install-plugin shiro安装,但是这里使用最新的快照版本。不需要用shell安装只需要在项目的BuildConfig.groovy中增加插件的引用即可
    plugins {        runtime ":hibernate:$grailsVersion"        runtime ":jquery:1.8.3"        runtime ":resources:1.1.6"        runtime ":shiro:1.2.0-SNAPSHOT"
  • 当我们修改了BuildConfig.groovy文件后,需要对系统进行重新编译,修改才能生效
$ grails compile
  • 现在插件已经安装好了,下一步建立一个初步的脚手架,执行这个shell后,系统会帮我们生成一系列的脚手架文件,这个--prefix=[包路径]是可选项,如果使用包路径,不要忘记最后面的那个"."
$ grails shiro-quick-start --prefix=com.example.| Created file grails-app/domain/com/example/User.groovy| Created file grails-app/domain/com/example/Role.groovy| Created file grails-app/realms/com/example/DbRealm.groovy| Created file grails-app/controllers/com/example/AuthController.groovy| Created file grails-app/views/auth/login.gsp| Created file grails-app/conf/com/example/SecurityFilters.groovy

 配置

Bootstrap.groovy

 1 import com.example.Role 2 import com.example.User 3  4 class BootStrap { 5  6     def shiroSecurityService 7  8     def init = { servletContext -> 9         // Create the admin role10         def adminRole = Role.findByName('ROLE_ADMIN') ?:11                 new Role(name: 'ROLE_ADMIN').save(flush: true, failOnError: true)12 13         // Create the user role14         def userRole = Role.findByName('ROLE_USER') ?:15                 new Role(name: 'ROLE_USER').save(flush: true, failOnError: true)16 17         // Create an admin user18         def adminUser = User.findByUsername('admin') ?:19                 new User(username: "admin",20                 passwordHash: shiroSecurityService.encodePassword('password'))21                 .save(flush: true, failOnError: true)22 23         // Add roles to the admin user24         assert adminUser.addToRoles(adminRole)25         .addToRoles(userRole)26         .save(flush: true, failOnError: true)27 28         // Create an standard user29         def standardUser = User.findByUsername('joe') ?:30                 new User(username: "joe",31                 passwordHash: shiroSecurityService.encodePassword('password'))32                 .save(flush: true, failOnError: true)33 34         // Add role to the standard user35         assert standardUser.addToRoles(userRole)36         .save(flush: true, failOnError: true)37 38     }39     def destroy = {40     }41 }
  • 在代码第6行,引入了shiro的安全服务,并使用服务的encodePassword方法进行加密
  • 在代码第9到15行,新增admin和user两个角色
  • 在代码第17到21行,新增一个账号为admin的用户,并对password进行加密
  • 在代码第23到26行,给admin用户进行角色授权
  • 在代码第28到36行,给user用户进行角色授权

运行测试一下效果

$grails run-appor$grails -Dserver.port=8888 run-app

登录http://localhost:8080/shiro-example,点com.example.AuthController控制器,系统弹出登录窗口,输入账号和密码后,系统返回主界面,什么都没发生过。这是因为我们没有需要验证的界面,下面再增加一点东西

  • 新增一个控制器
$ grails create-controller com.example.Home
  • 给这个控制器增加三个action
 1 package com.example 2  3 class HomeController { 4  5     def index() { 6         render "这个页面不需要验证" 7     } 8  9     def secured() {10         render "这个页面需要user角色才能访问"11     }12 13     def admin() {14         render "这个页面需要admin角色才能访问"15     }16 }
  • 正如我们看到的,我可以分别登陆不同的视图,特定的角色才能返回正常的结果
  • 如果权限不够的用户登录到了相应页面,系统提示“You do not have permission to access this page”
  • 如果我们现在运行,并访问,不管登录到index、secured还是admin,系统都会提示“You do not have permission to access this page”

现在,分别给不同的action进行授权,打开SecurityFilters.groovy,拷贝如下代码

 1 package com.example 2  3 /** 4  * Generated by the Shiro plugin. This filters class protects all URLs 5  * via access control by convention. 6  */ 7 class SecurityFilters { 8  9     /**10      * Array of controller/action combinations which will be skipped from authentication11      * if the controller and action names match. The action value can also be '*' if it12      * encompasses all actions within the controller.13      */14     static nonAuthenticatedActions = [15             [controller: 'home', action: 'index']16     ]17 18     /**19      * Array of controller/action combinations that will be authenticated against the user's20      * role. The map also includes the roles which the controller/action pair will match21      * against.22      */23     static authenticatedActions = [24             [controller: 'home', action: 'secured', roles: ['ROLE_ADMIN', 'ROLE_USER']],25             [controller: 'home', action: 'admin', roles: ['ROLE_ADMIN']]26     ]27 28     def filters = {29 30         all(controller: '*', action: '*') {31             before = {32 33                 // Determine if the controller/action belongs is not to be authenticated34                 def needsAuth = !nonAuthenticatedActions.find {35                     (it.controller == controllerName) &&36                             ((it.action == '*') || (it.action == actionName))37                 }38 39                 if (needsAuth) {40 41                     // Get the map within the authenticated actions which pertain to the current42                     // controller and view.43                     def authRoles = authenticatedActions.find {44                         (it.controller == controllerName) &&45                                 ((it.action == '*') || (it.action == actionName))46                     }47 48                     if (authRoles) {49 50                         // Perform the access control for each of the roles provided in the authRoles51                         accessControl {52                             authRoles.roles.each { roleName ->53                                 role(roleName)54                             }55                         }56                     }57 58                     // Skip authentication if the authRoles was not found59                     else {60                         return true61                     }62                 }63 64                 // Skip authentication if no auth is needed65                 else {66                     return true67                 }68             }69         }70 71     }72 }
  • 代码第14到16行,登记不需要授权的action
  • 代码第23到26行,登记需要授权的action,并指定相应的角色

现在,大功告成,再使用不同的角色,访问不同的页面,应该可以得到不同的效果

http://localhost:8080/shiro-example/home/index : non

http://localhost:8080/shiro-example/home/secured : user,admin

http://localhost:8080/shiro-example/home/admin : admin

原创粉丝点击