文章目录
表结构设计
一个用户有多个角色,一个角色对应多个权限,总体来讲是五张表
用户表
作用
用于验证用户帐号密码
表结构
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '',
`password` text CHARACTER SET utf8 COLLATE utf8_bin,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_NAME` (`name`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=3597 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
用户——角色关联表
作用
用于通过用户ID查找角色ID
表结构
CREATE TABLE `user_role` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`user_id` bigint(11) NOT NULL,
`role_id` bigint(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6802 DEFAULT CHARSET=utf8
角色表
作用
用于标识用户角色
表结构
CREATE TABLE `role` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4629 DEFAULT CHARSET=utf8
角色——权限关联表
作用
用过角色ID,查找权限ID
表结构
CREATE TABLE `role_permission` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`role_id` bigint(11) NOT NULL,
`permission_id` bigint(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4651 DEFAULT CHARSET=utf8
权限表
作用
定义用户有哪些权限
表结构
CREATE TABLE `permission` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`resource` varchar(255) NOT NULL,
`action` varchar(255) NOT NULL,
`instance` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3224 DEFAULT CHARSET=utf8
重写登录验证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("ApiRealm.doGetAuthenticationInfo");
String username = (String) token.getPrincipal(); // 得到用户名
String password = new String((char[]) token.getCredentials()); // 得到密码
System.out.println("password = " + password);
User user = userMapper.findUser(username);
System.out.println("user = " + user);
if (!password.equals(user.getPassword())) {
return null;
}
SimpleAuthenticationInfo authInf = new SimpleAuthenticationInfo(
username, password, getName());
return authInf;
}
重写权限检查验证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal(); // 得到用户名
try {
System.out.println("username = " + username);
UserAuthInfo authInfo = userMapper.selectUserAuthInfo(username);
if (authInfo != null) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Gson gson = new Gson();
List<RoleInfo> userRole = authInfo.getUserRole();
System.out.println("userRole = " + gson.toJson(userRole));
for (RoleInfo userRoleInfo : userRole) {
info.addRole(userRoleInfo.getRole());
for (PermissionInfo rolePermission : userRoleInfo
.getRolePermission()) {
String permission = rolePermission.getResource() + ":"
+ rolePermission.getAction() + ":"
+ rolePermission.getInstance();
info.addStringPermission(permission);
}
}
return info;
} else {
return null;
}
} catch (Exception e) {
return null;
}
}
表查询
SELECT `user`.id AS user_id ,`user`.`name` AS user_name,
role.id AS role_id,role.name AS role_name,
permission.id AS permission_id,permission.resource,
permission.action,permission.instance
from `user`
INNER JOIN user_role on `user`.id=user_role.user_id
INNER JOIN role on user_role.role_id=role.id
INNER JOIN role_permission ON role_permission.role_id=role.id
INNER JOIN permission ON role_permission.permission_id=permission.id
WHERE `user`.`name`= 'yaoyan'
MyBatis
java
@SqlMapper
public interface UserMapper {
User findUser(String name);
UserAuthInfo selectUserAuthInfo(String name);
}
xml
<?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.mybatis.mapper.UserMapper">
<select id="findUser" resultType="com.mybatis.entity.User" parameterType="java.lang.String">
select * from user where `user`.`name` = #{0,jdbcType=VARCHAR}
</select>
<resultMap id="UserAuthInfoMap" type="com.mybatis.entity.UserAuthInfo">
<id column="user_id" property="userId" jdbcType="BIGINT" />
<result column="user_name" property="username" jdbcType="VARCHAR" />
<collection property="userRole"
ofType="com.mybatis.entity.RoleInfo">
<id property="id" column="role_id" />
<result property="role" column="role_name" />
<collection property="rolePermission"
ofType="com.mybatis.entity.PermissionInfo">
<id property="id" column="permission_id" />
<result property="resource" column="resource" />
<result property="action" column="action" />
<result property="instance" column="instance" />
</collection>
</collection>
</resultMap>
<select id="selectUserAuthInfo" parameterType="java.lang.String"
resultMap="UserAuthInfoMap">
SELECT `user`.id AS user_id ,`user`.`name` AS user_name,
role.id AS role_id,role.name AS role_name,
permission.id AS permission_id,permission.resource,
permission.action,permission.instance
from `user`
INNER JOIN user_role on `user`.id=user_role.user_id
INNER JOIN role on user_role.role_id=role.id
INNER JOIN role_permission ON role_permission.role_id=role.id
INNER JOIN permission ON role_permission.permission_id=permission.id
WHERE `user`.`name`= #{0,jdbcType=VARCHAR}
</select>
</mapper>
测试
代码
@GET
@Path("/hello")
public Response sayHello() {
servletResponse.setContentType("text/html;charset=utf-8");
StringBuilder stringBuilder = new StringBuilder();
SecurityUtils.setSecurityManager(new DefaultSecurityManager(apiRealm));
AuthenticationToken token = new UsernamePasswordToken("yaoyan",
"1231231");
Subject subject = SecurityUtils.getSubject();
boolean ret = false;
try {
subject.login(token);
ret = true;
} catch (AuthenticationException e) {
ret = false;
}
if (ret == true) {
stringBuilder.append("登录成功 ");
if (subject.hasRole("ikun")) {
stringBuilder.append("有角色rd ");
} else {
stringBuilder.append("没有角色rd ");
}
if (subject.isPermitted("testtype:write:3")) {
stringBuilder.append("有权限 write ");
} else {
stringBuilder.append("没有权限 write ");
}
} else {
stringBuilder.append("登录失败");
}
return Response.status(200).entity(stringBuilder.toString()).build();
}