SpringMVC下的Shiro权限框架的使用

阅读更多

SpringMVC+Shiro权限管理

 

博文目录

  1. 权限的简单描述
  2. 实例表结构及内容及POJO
  3. Shiro-pom.xml
  4. Shiro-web.xml
  5. Shiro-MyShiro-权限认证,登录认证层
  6. Shiro-applicationContext-shiro.xml
  7. HomeController
  8. 三个JSP文件

 什么是权限呢?举个简单的例子:
我有一个论坛,注册的用户分为normal用户,manager用户。
对论坛的帖子的操作有这些:
添加,删除,更新,查看,回复
我们规定:
normal用户只能:添加,查看,回复
manager用户可以:删除,更新

normal,manager对应的是角色(role)
添加,删除,更新等对应的是权限(permission)

我们采用下面的逻辑创建权限表结构(不是绝对的,根据需要修改)

一个用户可以有多种角色(normal,manager,admin等等)
一个角色可以有多个用户(user1,user2,user3等等)
一个角色可以有多个权限(save,update,delete,query等等)
一个权限只属于一个角色(delete只属于manager角色)


SpringMVC下的Shiro权限框架的使用_第1张图片
 

 我们创建四张表:
t_user用户表:设置了3个用户
-------------------------------
id + username   + password
---+----------------+----------
1  +   tom           +  000000
2  +   jack           +  000000
3  +   rose          +  000000
---------------------------------
t_role角色表:设置3个角色
--------------
id + rolename 
---+----------
1  + admin
2  + manager
3  + normal
--------------
t_user_role用户角色表:tom是admin和normal角色,jack是manager和normal角色,rose是normal角色
---------------------
user_id  +  role_id
-----------+-----------
1            +     1
1            +     3
2            +     2
2            +     3
3            +     3
---------------------
t_permission权限表:admin角色可以删除,manager角色可以添加和更新,normal角色可以查看
-----------------------------------
id  +  permissionname  +  role_id
----+------------------------+-----------
1   +   add                     +     2
2   +   del                       +    1
3   +   update                +     2
4   +   query                   +    3
-----------------------------------

 

 建立对应的POJO:

package com.cn.pojo;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name="t_user")
public class User {

	private Integer id;
	@NotEmpty(message="用户名不能为空")
	private String username;
	@NotEmpty(message="密码不能为空")
	private String password;
	private List roleList;//一个用户具有多个角色
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	@ManyToMany
	@JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="user_id")},inverseJoinColumns={@JoinColumn(name="role_id")})
	public List getRoleList() {
		return roleList;
	}
	public void setRoleList(List roleList) {
		this.roleList = roleList;
	}
	
	@Transient
	public Set getRolesName(){
		List roles=getRoleList();
		Set set=new HashSet();
		for (Role role : roles) {
			set.add(role.getRolename());
		}
		return set;
	}
	
}

 

package com.cn.pojo;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="t_role")
public class Role {

	private Integer id;
	private String rolename;
	private List permissionList;//一个角色对应多个权限
	private List userList;//一个角色对应多个用户
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getRolename() {
		return rolename;
	}
	public void setRolename(String rolename) {
		this.rolename = rolename;
	}
	@OneToMany(mappedBy="role")
	public List getPermissionList() {
		return permissionList;
	}
	public void setPermissionList(List permissionList) {
		this.permissionList = permissionList;
	}
	@ManyToMany
	@JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="role_id")},inverseJoinColumns={@JoinColumn(name="user_id")})
	public List getUserList() {
		return userList;
	}
	public void setUserList(List userList) {
		this.userList = userList;
	}
	
	@Transient
	public List getPermissionsName(){
		List list=new ArrayList();
		List perlist=getPermissionList();
		for (Permission per : perlist) {
			list.add(per.getPermissionname());
		}
		return list;
	}
}

 

package com.cn.pojo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="t_permission")
public class Permission {

	private Integer id;
	private String permissionname;
	private Role role;//一个权限对应一个角色
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getPermissionname() {
		return permissionname;
	}
	public void setPermissionname(String permissionname) {
		this.permissionname = permissionname;
	}
	@ManyToOne
	@JoinColumn(name="role_id")
	public Role getRole() {
		return role;
	}
	public void setRole(Role role) {
		this.role = role;
	}
	
}

 

 使用SHIRO的步骤:
1,导入jar
2,配置web.xml
3,建立dbRelm
4,在Spring中配置

pom.xml中配置如下:


  4.0.0
  com.hyx
  springmvc
  war
  0.0.1-SNAPSHOT
  springmvc Maven Webapp
  http://maven.apache.org
  
    
      junit
      junit
      3.8.1
      test
    
    
    
		org.springframework
		spring-webmvc
		3.2.4.RELEASE
	
    
    
		org.springframework
		spring-jdbc
		3.2.4.RELEASE
	
	
		org.springframework
		spring-orm
		3.2.4.RELEASE
	
	
    
    
		org.hibernate
		hibernate-core
		4.2.5.Final
	
	
		org.hibernate
		hibernate-ehcache
		4.2.5.Final
	
	
		net.sf.ehcache
		ehcache
		2.7.2
	
	
		commons-dbcp
		commons-dbcp
		1.4
	
    
		mysql
		mysql-connector-java
		5.1.26
	
	
	
		javax.inject
		javax.inject
		1
	        
	
	
	
	
		org.hibernate
		hibernate-validator
		5.0.1.Final
	
    
    
		org.codehaus.jackson
		jackson-mapper-asl
		1.9.13
	        
    
    
		javax.servlet
		jstl
		1.2
	
	
	
	  javax.servlet
	  servlet-api
	  2.5
	
	
	  
      
      org.apache.shiro  
      shiro-core  
      1.2.2  
      
      
      org.apache.shiro  
      shiro-web  
      1.2.2  
      
      
      org.apache.shiro  
      shiro-spring  
      1.2.2  
     
  
  
  
    springmvc
    
    
    	
		  org.mortbay.jetty
		  jetty-maven-plugin
		  
		    10
		    
		      /
		    
		    
		    
		       
		          80
		          60000
		       
		    
		  
		
    
  

 

 web.xml中的配置:



  Archetype Created Web Application
  
  
  
  	opensessioninview
  	org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
  
  
  	opensessioninview
  	/*
  
  
  
  
  	springmvc
  	org.springframework.web.servlet.DispatcherServlet
  	1
  
  
  	springmvc
  	
  	/
  
  
  
  
	contextConfigLocation
	classpath:applicationContext*.xml
  
  
	
		org.springframework.web.context.ContextLoaderListener
	
  
  
    
    
    shiroFilter  
    org.springframework.web.filter.DelegatingFilterProxy  
    
    
    shiroFilter  
    /*  
  
  

 

 

package com.cn.service;

import java.util.List;

import javax.inject.Inject;

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.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cn.pojo.Role;
import com.cn.pojo.User;

@Service
@Transactional
public class MyShiro extends AuthorizingRealm{

	@Inject
	private UserService userService;
	/**
	 * 权限认证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		//获取登录时输入的用户名
		String loginName=(String) principalCollection.fromRealm(getName()).iterator().next();
		//到数据库查是否有此对象
		User user=userService.findByName(loginName);
		if(user!=null){
			//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
			SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
			//用户的角色集合
			info.setRoles(user.getRolesName());
			//用户的角色对应的所有权限,如果只使用角色定义访问权限,下面的四行可以不要
			List roleList=user.getRoleList();
			for (Role role : roleList) {
				info.addStringPermissions(role.getPermissionsName());
			}
			return info;
		}
		return null;
	}

	/**
	 * 登录认证;
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authenticationToken) throws AuthenticationException {
		//UsernamePasswordToken对象用来存放提交的登录信息
		UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
		//查出是否有此用户
		User user=userService.findByName(token.getUsername());
		if(user!=null){
			//若存在,将此用户存放到登录认证info中
			return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
		}
		return null;
	}

}

 

 在spring的配置文件中配置,为了区别spring原配置和shiro我们将shiro的配置独立出来。

applicationContext-shiro.xml




	
	  
        
          
        
          
    
    
    
     
    	 
         
         
          
        
          
        
          
        
          
              
            	
            	/static/**=anon
            	
            	/user=perms[user:query]
            	
            	/user/add=roles[manager]
            	/user/del/**=roles[admin]
            	/user/edit/**=roles[manager]
            	  
                /** = authc
              
          
    
    
    
      
     
	

 

 用于登录,登出,权限跳转的控制:

package com.cn.controller;

import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.cn.pojo.User;

@Controller
public class HomeController {

	@RequestMapping(value="/login",method=RequestMethod.GET)
	public String loginForm(Model model){
		model.addAttribute("user", new User());
		return "/login";
	}
	
	@RequestMapping(value="/login",method=RequestMethod.POST)
	public String login(@Valid User user,BindingResult bindingResult,RedirectAttributes redirectAttributes){
		try {
			if(bindingResult.hasErrors()){
				return "/login";
			}
			//使用权限工具进行用户登录,登录成功后跳到shiro配置的successUrl中,与下面的return没什么关系!
			SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
			return "redirect:/user";
		} catch (AuthenticationException e) {
			redirectAttributes.addFlashAttribute("message","用户名或密码错误");
			return "redirect:/login";
		}
	}
	
	@RequestMapping(value="/logout",method=RequestMethod.GET)  
    public String logout(RedirectAttributes redirectAttributes ){ 
		//使用权限管理工具进行用户的退出,跳出登录,给出提示信息
        SecurityUtils.getSubject().logout();  
        redirectAttributes.addFlashAttribute("message", "您已安全退出");  
        return "redirect:/login";
    } 
	
	@RequestMapping("/403")
	public String unauthorizedRole(){
		return "/403";
	}
}

 

 三个主要的JSP:
login.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>


  
    My JSP 'MyJsp.jsp' starting page
  
  
  
  	

登录页面----${message }

用户名:
密   码:
submit

 

 user.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>


  
    用户列表
  
  
	

${message }

用户列表--添加用户---退出登录

权限列表

用户已经登录显示此内容 manager角色登录显示此内容 admin角色登录显示此内容 normal角色登录显示此内容 **manager or admin 角色用户登录显示此内容** -显示当前登录用户名 add权限用户显示此内容 query权限用户显示此内容 不具有user:del权限的用户显示此内容

 

 

 403.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>


  
    权限错误
  
  
  
  	

对不起,您没有权限请求此连接!

 

 

 

  • SpringMVC下的Shiro权限框架的使用_第2张图片
  • 大小: 109.1 KB
  • 查看图片附件

你可能感兴趣的:(SpringMVC,Shiro,权限框架,权限管理)