关于shiro的简单使用(2) --- 权限认证

之前已经熟悉了认证登陆,接下来尝试一下权限控制。我接触的权限控制的方式主要有2种,一种是粗粒度URL级别的权限控制,还有一种就是细粒度方法级别权限控制。具体的这2种方式的定义和说明请自行查找资料。这里使用的是细粒度的URL级别的权限控制。

1 配置

这个配置在认证登陆那里已经写过,将主要的内容在贴过来:

	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/login" />
		<property name="successUrl" value="/index" />
		<property name="unauthorizedUrl" value="/unauthorized" />
		<property name="filterChainDefinitions">
			<value>
				/index = authc
				/login = anon
				/logout = logout
				/common/**= anon
				/** = authc
			</value>
		</property>
	</bean>

PS:anon—是可以匿名访问的,比如登陆页面,还有部分资源文件,authc—是需要权限认证的,比如登陆后的首页等。

2 实现

2.1 建类

1.用户类

package com.yzpt.entity.system;

import lombok.Getter;
import lombok.Setter;

/**
 * Description: 用户类
 *
 * @author yzp
 *
 * @date 2019年9月25日
 *
 */
@Setter
@Getter
public class User {
	private Integer id;				// 用户id
	private String userName;		// 用户账号
	private String nickName;		// 用户昵称
	private String password;		// 用户密码
	private String salt;			// 加密密码的盐
	private Integer status;			// 用户状态,0:创建未认证(比如没有激活,没有输入验证码等) --等待验证的用户,1:正常状态,2:用户被锁定 								
	private String age;				// 用户年龄
	private String sex;				// 用户性别
	private String mail;         	// 用户邮箱
	private String photo;			// 用户头像
}

2.角色类

package com.yzpt.entity.system;

import lombok.Getter;
import lombok.Setter;

/**
 * Description: 角色类
 *
 * @author yzp
 *
 * @date 2019年9月25日
 *
 */
@Setter
@Getter
public class Role {
	private Integer id;							// 角色id
	private String roleName;  					// 角色名称
	private String description;         		// 角色描述
	private Boolean avaliable = Boolean.FALSE;	// 是否可用,如果不可用将不会添加给用户
	private String beiyong;             		// 备用字段
}

3.权限类

package com.yzpt.entity.system;

import lombok.Getter;
import lombok.Setter;

/**
 * Description: 权限类
 *
 * @author yzp
 *
 * @date 2019年9月25日
 *
 */
@Setter
@Getter
public class Permission {
	private Integer id;								// 权限id
	private String permissionName;					// 权限名称
	private String reseourceType;					// 资源类型 [menu|button]
	private String url;								// 资源路径
	private String permissionCode;					// 权限代码 menu例子:role:*  button例子:role:create,role:update,role:delete,role:view
	private Long parentId;							// 父编号
	private String parentIds;						// 父编号列表
	private Boolean available = Boolean.FALSE;		// 是否有效
	private String beiyong;							// 备用字段
}

PS:每个用户可以拥有多个角色,每个角色可以拥有多个权限,上述类中有的属性不一定能用到。

2.2 建表

1.用户表

CREATE TABLE `t_user` (
  `id` int(100) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户账号',
  `nick_name` varchar(255) DEFAULT NULL COMMENT '用户昵称',
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
  `salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '加密密码的盐',
  `status` int(1) NOT NULL COMMENT '用户状态,0:创建未认证(比如没有激活,没有输入验证码等) --等待验证的用户,1:正常状态,2:用户被锁定',
  `age` varchar(20) DEFAULT NULL COMMENT '用户年龄',
  `sex` varchar(20) DEFAULT NULL COMMENT '用户性别',
  `mail` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户邮箱',
  `photo` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '头像地址',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modified_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2.角色表

CREATE TABLE `t_role` (
  `id` int(100) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `role_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色描述',
  `status` int(1) DEFAULT NULL COMMENT '状态: 1.有效  2.删除',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modified_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3.权限表

CREATE TABLE `t_permission` (
  `id` int(100) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `permission_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限名称',
  `reseource_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '资源类型',
  `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源路径',
  `permission_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限代码 menu例子:role:*  button例子:role:create,role:update,role:delete,role:view',
  `parent_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '父编号',
  `parent_ids` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '父编号列表',
  `status` int(1) DEFAULT NULL COMMENT '状态:1.有效  2.删除',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modified_time` datetime DEFAULT NULL COMMENT '修改时间',
  `sort` int(100) DEFAULT NULL COMMENT '排序',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

4.用户_角色表

CREATE TABLE `t_user_role` (
  `id` int(100) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_id` int(100) NOT NULL COMMENT '用户id',
  `role_id` int(100) NOT NULL COMMENT '角色id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modified_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

5.角色_权限表

CREATE TABLE `t_role_permission` (
  `id` int(100) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `role_id` int(100) NOT NULL COMMENT '角色id',
  `permission_id` int(100) NOT NULL COMMENT '权限id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modified_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3 代码实现

1.代码配置

	// 权限认证
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		User user = (User)SecurityUtils.getSubject().getPrincipal();
		if(user != null) {
			// 获取角色
			Integer userId = user.getId();
			List<Role> roles = userMapper.getRolesByUserId(userId);
			List<Permission> permissions = new ArrayList<Permission>();
			// 获取权限
			if(roles != null && roles.size() > 0) {
				for(int i = 0 ; i < roles.size(); i++) {
					List<Permission> ps = userMapper.getPermissionsByRoleId(roles.get(i).getId());
					if(ps != null) {
						permissions.addAll(ps);
					}
					// 角色
					authorizationInfo.addRole(roles.get(i).getRoleName());
				}
			}
			// 权限
			if(permissions != null && permissions.size() > 0) {
				for(int i = 0 ; i < permissions.size() ; i++) {
					authorizationInfo.addStringPermission(permissions.get(i).getPermissionCode());
				}
			}
		}
		return authorizationInfo;
	}

2.代码调用

/**  
	 * Description: 用户列表查询
	 *
	 * @param request
	 * @param response
	 * @return  
	 *
	 */  
	@RequestMapping(value = "/userList")
	@RequiresPermissions("user:view")
    public String userInfo(HttpServletRequest request, HttpServletResponse response) {
    	String result = "";
    	try {
    		// 分页查询
    		int pageNo = request.getParameter("pageNo") != null ? Integer.valueOf(request.getParameter("pageNo")) : 1;
    		int pageSize = 10;
    		// 查询所有的用户
			Page<User> page = userService.findByPage(pageNo, pageSize);
    		User currentUser = (User)SecurityUtils.getSubject().getPrincipal();
    		request.setAttribute("page", page);
    		request.setAttribute("currentUser", currentUser);
    		result = "userInfoList";
		} catch (Exception e) {
			result = "error";
			logger.info("用户列表查询失败 ----- "+e);
		}
    	return result;
    }

PS:网上查找的资料很多都是在业务层添加权限验证注解的,如果需要在控制层可以通过注解的方式来进行权限验证,需要将以下配置在SpringMVC的配置中:

	<!-- shiro生命周期处理器 -->
	<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

	<!-- AOP式方法级权限检查 -->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor">
		<property name="proxyTargetClass" value="true" />
	</bean>

	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>
	
	<!-- 无权访问跳转页面 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
	    <property name="exceptionMappings">  
	        <props>  
	            <prop key="org.apache.shiro.authz.UnauthorizedException">
	                ../../unauthorized
	            </prop>  
	            <prop key="org.apache.shiro.authz.UnauthenticatedException">
	                ../../unauthorized
	            </prop>  
	        </props>  
	    </property>  
	</bean> 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值