NEO

蜀道难,难于上青天!

导航

20130116-使用Grails Shiro Plugin实现身份验证02

Posted on 2013-01-15 17:20  页面载入出错  阅读(1102)  评论(0编辑  收藏  举报

上一篇把Shiro部署到Grails上了,并且可以正常运行,虽然可以使用grails generate-all domain方式生成CRUD的脚手架增加用户或角色,但是出于业务的角度考虑,我们不希望所有人都可以增加用户信息,所以,我们新增加一个注册的功能,供没有账号的人注册自己的个人资料,而有admin权限的人可以登录到系统使用CRUD去维护这些账户信息。

注册

  • 现在创建一个SignupController,用来处理注册过程
$grails create-controller com.example.SignupController
  • 在Controller中增加注册方法
 1 package com.example
 2 
 3 import org.apache.shiro.authc.UsernamePasswordToken
 4 import org.apache.shiro.SecurityUtils
 5 
 6 class SignupController {
 7     def shiroSecurityService
 8 
 9     def index() {
10         User user = new User()
11         [user: user]
12     }
13 
14     def register() {
15         // Check to see if the username already exists
16         def user = User.findByUsername(params.username)
17         if (user) {
18             flash.message = "User already exists with the username '${params.username}'"
19             redirect(action:'index')
20         } else { // User doesn't exist with username. Let's create one
21             // Make sure the passwords match
22             if (params.password != params.password2) {
23                 flash.message = "Passwords do not match"
24                 redirect(action:'index')
25             } else { // Passwords match. Let's attempt to save the user
26                 // Create user
27                 user = new User(username: params.username,passwordHash: shiroSecurityService.encodePassword(params.password))
28 
29                 if (user.save()) {
30                     // Add USER role to new user
31                     user.addToRoles(Role.findByName('ROLE_USER'))
32                     // Login user
33                     def authToken = new UsernamePasswordToken(user.username, params.password)
34                     SecurityUtils.subject.login(authToken)
35 
36                     redirect(controller: 'home', action: 'secured')
37                 }else {}
38             }
39         }
40     }
41 }
  • 在这个Controller中定义了index和register两个action
  • index action用来显示注册界面
  • register action处理注册结果,如果注册成功则redirect到HomeController下的secured action

下面增加一个index.gsp界面,当访问http://localhost:8080/shiro-example/home/index时跳转到注册界面

 1 <%@ page contentType="text/html;charset=UTF-8"%>
 2 <html>
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 5 <title>Register</title>
 6 <meta name="layout" content="main" />
 7 </head>
 8 
 9 <body>
10     <h1>Signup</h1>
11     <g:if test="${flash.message}">
12         <div class="alert alert-info">${flash.message}</div>
13     </g:if>
14     <g:hasErrors bean="${user}">
15         <div class="alert alert-error"><g:renderErrors bean="${user}" as="list" /></div>
16     </g:hasErrors>
17 
18     <g:form action="register">
19         <fieldset class="form"><g:render template="register"/></fieldset>
20         
21         <fieldset class="buttons">
22             <g:submitButton name="submit" value="Submit"/>
23         </fieldset>
24     </g:form>
25 
26 </body>
27 </html>

在这里,使用<g:render template="register"/>引用了一个register模板,grails会去view下的当前gsp文件的相同目录中去找_register.gsp文件。所以,再建一个_register.gsp文件,定义表单内容

 1 <%@ page import="com.example.User" %>
 2 
 3 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'username', 'error')} required">
 4     <label for="username">
 5         <g:message code="user.username.label" default="Username" />
 6         <span class="required-indicator">*</span>
 7     </label>
 8     <g:textField name="username" required="" value="${userInstance?.username}"/>
 9 </div>
10 
11 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'passwordHash', 'error')} required">
12     <label for="password">Password</label>
13     <span class="required-indicator">*</span>
14     <g:passwordField name="password" value=""/>
15 </div>
16 
17 <div class="fieldcontain ${hasErrors(bean: userInstance, field: 'passwordHash', 'error')} required">
18     <label for="password">Confirm Password</label>
19     <span class="required-indicator">*</span>
20     <g:passwordField name="password2" value=""/>
21 </div>