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;
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

posted @ 2013-06-11 21:05  projack  阅读(7813)  评论(5编辑  收藏  举报