前言
相比有做过企业级开发的童鞋应该都有做过权限安全之类的功能吧,最先开始我采用的是建用户表
,角色表
,权限表
,之后在拦截器中对每一个请求进行拦截,再到数据库中进行查询看当前用户是否有该权限,这样的设计能满足大多数中小型系统的需求。不过这篇所介绍的Shiro能满足之前的所有需求,并且使用简单,安全性高,而且现在越来越的多企业都在使用Shiro,这应该是一个收入的你的技能库。
创建自定义MyRealm
类
有关Shiro的基础知识我这里就不过多介绍了,直接来干货,到最后会整合Spring来进行权限验证。
首先在使用Shiro的时候我们要考虑在什么样的环境下使用:
- 登录的验证
- 对指定角色的验证
- 对URL的验证
基本上我们也就这三个需求,所以同时我们也需要三个方法:
1. findUserByUserName(String username)
根据username查询用户,之后Shiro会根据查询出来的User的密码来和提交上来的密码进行比对。
2. findRoles(String username)
根据username查询该用户的所有角色,用于角色验证。
3. findPermissions(String username)
根据username查询他所拥有的权限信息,用于权限判断。
下面我贴一下我的mapper代码(PS:该项目依然是基于之前的SSM,不太清楚整合的请看SSM一)。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.crossoverJie.dao.T_userDao" >
<resultMap id="BaseResultMap" type="com.crossoverJie.pojo.T_user" >
<result property="id" column="id"/>
<result property="userName" column="userName"/>
<result property="password" column="password"/>
<result property="roleId" column="roleId"/>
</resultMap>
<sql id="Base_Column_List" >
id, username, password,roleId
</sql>
<select id="findUserByUsername" parameterType="String" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from t_user where userName=#{userName}
</select>
<select id="findRoles" parameterType="String" resultType="String">
select r.roleName from t_user u,t_role r where u.roleId=r.id and u.userName=#{userName}
</select>
<select id="findPermissions" parameterType="String" resultType="String">
select p.permissionName from t_user u,t_role r,t_permission p
where u.roleId=r.id and p.roleId=r.id and u.userName=#{userName}
</select>
</mapper>
很简单只有三个方法,分别对应上面所说的三个方法。对sql
稍微熟悉点的童鞋应该都能看懂,不太清楚就拷到数据库中执行一下就行了,数据库的Sql
也在我的github
上。实体类就比较简单了,就只有四个字段以及get,set方法。我就这里就不贴了,具体可以去github
上fork
我的源码。
现在就需要创建自定义的MyRealm
类,这个还是比较重要的。继承至Shiro
的AuthorizingRealm
类,用于处理自己的验证逻辑,下面贴一下我的代码:
package com.crossoverJie.shiro;
import com.crossoverJie.pojo.T_user;
import com.crossoverJie.service.T_userService;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import javax.annotation.Resource;
import java.util.Set;
/**
* Created with IDEA
* Created by ${jie.chen} on 2016/7/14.
* Shiro自定义域
*/
public class MyRealm extends AuthorizingRealm {
@Resource
private T_userService t_userService;
/**
* 用于的权限的认证。
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = principalCollection.getPrimaryPrincipal().toString() ;
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo() ;
Set<String> roleName = t_userService.findRoles(username) ;
Set<String> permissions = t_userService.findPermissions(username) ;
info.setRoles(roleName);
info.setStringPermissions(permissions);
return info;
}
/**
* 首先执行这个登录验证
* @param token
* @return
* @throws AuthenticationException
*/