SpringMVC+Apache Shiro+JPA(hibernate)案例教学(四)基于Shiro验证用户权限,且给用户授权
最新项目比较忙,写文章的精力就相对减少了,但看到邮箱里的几个催更,还是厚颜把剩下的文档补上。
一、修改ShiroDbRealm类,实现它的doGetAuthorizationInfo方法
package org.shiro.demo.service.realm; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.shiro.demo.entity.Permission; import org.shiro.demo.entity.Role; import org.shiro.demo.entity.User; import org.shiro.demo.service.IUserService; public class ShiroDbRealm extends AuthorizingRealm{ @Resource(name="userService") private IUserService userService; protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //获取当前登录的用户名 String account = (String) super.getAvailablePrincipal(principals); List<String> roles = new ArrayList<String>(); List<String> permissions = new ArrayList<String>(); User user = userService.getByAccount(account); if(user != null){ if (user.getRoles() != null && user.getRoles().size() > 0) { for (Role role : user.getRoles()) { roles.add(role.getName()); if (role.getPmss() != null && role.getPmss().size() > 0) { for (Permission pmss : role.getPmss()) { if(!StringUtils.isEmpty(pmss.getPermission())){ permissions.add(pmss.getPermission()); } } } } } }else{ throw new AuthorizationException(); } //给当前用户设置角色 info.addRoles(roles); //给当前用户设置权限 info.addStringPermissions(permissions); return info; } /** * 认证回调函数,登录时调用. */ protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; User user = userService.getByAccount(token.getUsername()); if (user != null) { return new SimpleAuthenticationInfo(user.getAccount(), user .getPassword(), user.getNickname()); } else { return null; } } }
其实代码逻辑很简单,不过就是从principals获取当前用户名,然后读取user的role及permission信息。理解下就知道了。
二、初始化系统用户信息,利用Shiro Annotation实现权限认证。
(一)新建testInitSystemData junit测试类。(本着快速测试的目的,我们利用spring junit测试来初始化数据!o(╯□╰)o)
package org.shiro.demo.junit; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.shiro.demo.entity.Permission; import org.shiro.demo.entity.Role; import org.shiro.demo.entity.User; import org.shiro.demo.service.IBaseService; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml","classpath:spring-mvc.xml"}) @TransactionConfiguration(transactionManager="txManager",defaultRollback=false) public class testInitSystemData extends AbstractTransactionalJUnit4SpringContextTests{ @Resource(name="baseService") private IBaseService baseService; @Test public void initPermission() throws Exception{ List<Permission> list = new ArrayList<Permission>(); Permission pmss1 = new Permission(); pmss1.setName("新建用户"); pmss1.setDescription("新建用户"); pmss1.setPermission("user:create"); Permission pmss2 = new Permission(); pmss2.setName("编辑用户"); pmss2.setDescription("编辑用户"); pmss2.setPermission("user:edit"); Permission pmss3 = new Permission(); pmss3.setName("删除用户"); pmss3.setDescription("删除用户"); pmss3.setPermission("user:delete"); Permission pmss4 = new Permission(); pmss4.setName("审核用户"); pmss4.setDescription("审核用户"); pmss4.setPermission("user:audit"); list.add(pmss1); list.add(pmss2); list.add(pmss3); list.add(pmss4); for(Permission pms : list){ baseService.save(pms); } } @Test public void initAdminRole() throws Exception{ List<Permission> list = new ArrayList<Permission>(); list = (List<Permission>)baseService.getAll(Permission.class); Role role = new Role(); role.setName("administrator"); role.setDescription("系统管理员角色"); role.setPmss(list); baseService.save(role); } @Test public void initAdminUser(){ List<Role> list = new ArrayList<Role>(); String jpql = "from Role as o where o.name=?"; list = baseService.getByJpql(jpql, "administrator"); User user = new User(); user.setAccount("admin"); user.setPassword("123456"); user.setNickname("july"); user.setRoles(list); baseService.save(user); } }
(二)新建UserController类,新建用户注册页,并给用户注册上加上shiro权限验证,要求用户必须具备administrator角色
UserController.java
package org.shiro.demo.controller; import javax.annotation.Resource; import org.apache.shiro.authz.annotation.RequiresRoles; import org.shiro.demo.entity.User; import org.shiro.demo.service.IUserService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping(value = "/user") public class UserController { @Resource(name="userService") private IUserService userService; @RequestMapping(value = "/register",method=RequestMethod.POST) @ResponseBody @RequiresRoles("administrator") public boolean register(User user){ return userService.register(user); } }
@RequiresRoles("administrator")就是我们使用的Shirro注解了。
register.jsp
<%@ page language="java" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>shirodemo register page</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <form action="<%=basePath%>/user/register" method="post"> <ul> <li>姓 名:<input type="text" name="account" /> </li> <li>密 码:<input type="text" name="password" /> </li> <li>昵 称:<input type="text" name="nickname" /> </li> <li><input type="submit" value="确认" /> </li> </ul> </form> </body> </html>
(三)测试注解是否生效。
1、直接访问注册页面,点击注册。是否返回到了login.jsp页面?
2、登录后再访问注册页面,点击注册,看是否插入成功?
三、介绍Shiro Annotation及Shiro标签的用法。
为避免重复工作,请参考:http://kdboy.iteye.com/blog/1155450