SpringMVC+Apache Shiro+JPA(hibernate)案例教学(四)基于Shiro验证用户权限,且给用户授权

时间:2021-08-09 08:20:48

最新项目比较忙,写文章的精力就相对减少了,但看到邮箱里的几个催更,还是厚颜把剩下的文档补上。


一、修改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() > ) {
for (Role role : user.getRoles()) {
roles.add(role.getName());
if (role.getPmss() != null && role.getPmss().size() > ) {
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("");
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; import 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

转自:http://www.cnblogs.com/xql4j/archive/2013/06/11/3069398.html