Shiro学习(2)用户授权

前言:

如何实现用户授权的,即如何实现不同的用户有不同的权限,访问的资源不同?

不同用户属于不同的角色,不同的角色有不同的权限。

 

1、数据库如何设计

(1)多个用户可以是同一种角色,一个用户也可以是多种角色如:

角色表:t_role

用户表:t_user

用户角色表:t_user_role

小明和小红是管理员,小强和小张是普通用户;其实这里小明和小红也是普通用户,但管理员权限一般比普通用户多

(2)每一种角色都有多种权限

权限表:t_authority

角色权限表:t_role_authority

注意:此表不设置主键,但role_id设置成非空

管理员什么都能做,普通用户只能看到用户列表,不能进行其它操作

(3)要给t_role和t_authority两个表,分别添加一列角色码和权限码,就是用来描述角色和权限的,角色码和权限码会在用户授权时配置给当前登录成功的用户。

t_role:

t_authority:

2、举例说明

(1)实现目标:管理员登录显示用户列表,且能进行增删改;普通用户登录只显示用户列表,不能进行增删改查;(实现目标很简单,其实只需要角色码或者权限码一方,就能实现这个功能;我这里都用上,熟悉代码)

(2)后台代码

当用户验证完毕后,会自动执行用户授权;用户验证上一篇有详细讲解,这里附上整个代码;

UserRealm.java:

package shiro;
import java.util.Set;
import org.apache.shiro.SecurityUtils;
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.UnknownAccountException;
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.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import model.User;
import service.UserService;

public class UserRealm extends AuthorizingRealm {
	@Autowired
	private UserService userService;
	//用户认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //从token获得输入的账号
		String userName = token.getPrincipal()+"";
        //根据输入的账号到数据库去查找对应的用户
		User user = userService.findUserByUserName(userName);
        //用户不存在,表明账号不存在,则登录失败
		if(user==null){
			System.out.println("账号不存在");
			throw new UnknownAccountException();
		}else{
            //否则表明账号存在,判断密码是否正确
            /*注册用户时,我们若对密码进行先添加salt盐值后通过MD5加密,最后保存到数据库
             *那么在登录时,就需要根据当前输入的密码结合从数据库中取出的user的salt值,再经过
             *1024次MD5加密得到的字符串和user的密码进行对比,若相同才代表密码正确
             */
            //获得user的salt值
			ByteSource salt = ByteSource.Util.bytes(user.getSalt());
          
			//下面一句的作用是先比较账号,肯定相同;然后比较密码,相同则返回authenticationInfo,不同则抛异常 
            //如果验证成功,最终这里返回的信息authenticationInfo 的值与传入的第一个字段的值相同,这里就是账号
			SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(),user.getPassWord(),salt,getName());
            //能执行到这里,说明用户验证成功,记录当前登录进系统的用户
            Subject currentUser = SecurityUtils.getSubject();
			currentUser.getSession().setAttribute("CURR_USER", user);
			return authenticationInfo;
		}
	}
	
	//用户授权,用户认证成功后,就自动给当前用户进行授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//获取当前登录进系统的用户
        Subject currentUser = SecurityUtils.getSubject();
		User user = (User) currentUser.getSession().getAttribute("CURR_USER");
        //获取用户的角色码和权限码
		Set<String> currRoleCodes = userService.findUserCodesById(user.getId());
		Set<String> authorityCodes = userService.findAuthorityCodesById(user.getId());
		//为当前用户设置角色和权限,让shiro去管理
		SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
		simpleAuthorInfo.setRoles(currRoleCodes);
		simpleAuthorInfo.setStringPermissions(authorityCodes);
		return simpleAuthorInfo;
	}

	

	
}

UserController.java:

package controller;
import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import model.User;
import service.UserService;

@Controller
@RequestMapping("/user")
public class UserController {
	@Autowired
	private UserService userService;
	
	@RequestMapping("/list")
	@ResponseBody
       //属于user或者admin之一;修改logical为OR 即可
	@RequiresRoles(value={"role:commonUser","role:admin"},logical=Logical.OR)
	public Map<String,Object> list(Integer page,Integer rows) {
		return userService.findUser(page,rows);
	}
	
	@RequestMapping("/save")
	@ResponseBody
	@RequiresRoles("role:admin")
    //或者写下面一句,有这种权限才能做这个事;也可以根据不同情况都写上
    @RequiresPermissions("user:add")
	public Map<String,Object> save(User user) {
		int res =  userService.saveUser(user);
		Map<String,Object> map = new HashMap<String,Object>();
		if(res == 1) {
			map.put("code",200);
		}else{
			map.put("code", 500);
		}
		return map;
	}
	
	@RequestMapping("/del")
	@ResponseBody
	@RequiresRoles("role:admin")
    @RequiresPermissions("user:delete")
	public Map<String,Object> del(Integer id) {
		int res = userService.delUserById(id);
		Map<String,Object> map = new HashMap<String,Object>();
		if(res == 1) {
			map.put("code",200);
		}else{
			map.put("code", 500);
		}
		return map;
		
	}
	
	@RequestMapping("/update")
	@ResponseBody  
	@RequiresRoles("role:admin")
    @RequiresPermissions("user:update")
	public Map<String,Object> update(User user) {
		int res = userService.updateUser(user);
		Map<String,Object> map = new HashMap<String,Object>();
		if(res == 1) {
			map.put("code",200);
		}else{
			map.put("code", 500);
		}
		return map;
	}
	
	
    @RequestMapping("/login")
    public String Login(User user) {
	    Subject subject = SecurityUtils.getSubject();
		    try {
			    //用token保存输入的账号和密码
			    UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),user.getPassWord());
			    //进行用户验证
			    subject.login(token);
		    } catch (AuthenticationException e) {
			    e.printStackTrace();
		    }
	        return "redirect:/list.html";
     }
	
}

dao层对应的UserMapper.xml中添加:

<!--  shiro实现用户认证时,要根据输入的账号从数据库获得user -->
	<select id="findUserByUserName" resultMap="UserMap">
		select * from t_user where user_name=#{userName}
	</select>
	<!-- shiro实现用户授权时,要获取当前登录用户的角色码 ,权限码-->
	<select id="findUserCodesById" resultType="java.lang.String">
		SELECT role_code FROM `t_role` r
		LEFT JOIN `t_user_role` ur ON r.`id`=ur.`role_id` WHERE ur.`user_id`=#{id}
	</select>
	
	<select id="findAuthorityCodesById" resultType="java.lang.String">
		SELECT `authority_code` FROM `t_user_role` AS ur,`t_role_authority` AS ra,`t_authority` AS a
		WHERE ur.`role_id`=ra.`role_id` AND ra.`authority_id`=a.id AND ur.`user_id`=#{id}
	</select>

下一篇:一个完整的权限管理的案例;待续

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/Carl_changxin/article/details/82049151
今日推荐