1.数据库设计
#用户信息表
create table tb_users(
id int primary key auto_increment,
username varchar(60) not null,
password varchar(20) not null,
password_salt varchar(60)
);
insert into tb_users(username,password) values("zhagnsan","123456");
insert into tb_users(username,password) values("lisi","123456");
insert into tb_users(username,password) values("wangwu","123456");
insert into tb_users(username,password) values("zhaoliu","123456");
insert into tb_users(username,password) values("chenqi","123456");
#角色信息表
create table tb_roles(
role_id int primary key auto_increment,
role_name varchar(60) not null
);
insert into tb_roles(role_name) values("admin");
insert into tb_roles(role_name) values("cmanager");
insert into tb_roles(role_name) values("xmanager");
insert into tb_roles(role_name) values("kmanager");
insert into tb_roles(role_name) values("zmanager");
#权限信息表
create table tb_permissions(
permission_id int primary key auto_increment,
permission_code varchar(60) not null,
permission_name varchar(60)
);
insert into tb_permissions(permission_code,permission_name) values("sys:c:save","入库");
insert into tb_permissions(permission_code,permission_name) values("sys:c:delete","入库");
insert into tb_permissions(permission_code,permission_name) values("sys:c:update","修改");
insert into tb_permissions(permission_code,permission_name) values("sys:c:find","查询");
insert into tb_permissions(permission_code,permission_name) values("sys:x:save","新增订单");
insert into tb_permissions(permission_code,permission_name) values("sys:x:delete","删除订单");
insert into tb_permissions(permission_code,permission_name) values("sys:x:update","修改订单");
insert into tb_permissions(permission_code,permission_name) values("sys:x:find","查询订单");
insert into tb_permissions(permission_code,permission_name) values("sys:k:save","新增客户");
insert into tb_permissions(permission_code,permission_name) values("sys:k:delete","删除客户");
insert into tb_permissions(permission_code,permission_name) values("sys:k:update","修改客户");
insert into tb_permissions(permission_code,permission_name) values("sys:k:find","查询客户");
#用户角色表
create table tb_urs(
uid int not null,
rid int not null
);
insert into tb_urs(uid,rid) values(1,1);
insert into tb_urs(uid,rid) values(1,2);
insert into tb_urs(uid,rid) values(1,3);
insert into tb_urs(uid,rid) values(1,4);
insert into tb_urs(uid,rid) values(1,5);
insert into tb_urs(uid,rid) values(2,2);
insert into tb_urs(uid,rid) values(3,3);
insert into tb_urs(uid,rid) values(4,4);
insert into tb_urs(uid,rid) values(5,5);
#角色权限表
create table tb_rps(
rid int not null,
pid int not null
);
insert into tb_rps(rid,pid) values(2,1);
insert into tb_rps(rid,pid) values(2,2);
insert into tb_rps(rid,pid) values(2,3);
insert into tb_rps(rid,pid) values(2,4);
insert into tb_rps(rid,pid) values(3,5);
insert into tb_rps(rid,pid) values(3,4);
insert into tb_rps(rid,pid) values(3,6);
insert into tb_rps(rid,pid) values(3,7);
insert into tb_rps(rid,pid) values(3,8);
insert into tb_rps(rid,pid) values(3,9);
insert into tb_rps(rid,pid) values(3,10);
insert into tb_rps(rid,pid) values(3,11);
insert into tb_rps(rid,pid) values(3,12);
insert into tb_rps(rid,pid) values(4,11);
insert into tb_rps(rid,pid) values(4,12);
insert into tb_rps(rid,pid) values(5,4);
insert into tb_rps(rid,pid) values(5,8);
insert into tb_rps(rid,pid) values(5,12);
2.DAO实现
- 根据用户名查询用户信息
- 根据用户名查询当前用户的角色列表
- 根据用户名查询当前用户的权限列表
2.1创建spring boot项目整合mybatis
2.2创建bean
@Data
public class User {
private Integer userId;
private String userName;
private String userPwd;
private String pwdSalt;
}
2.3创建DAO
public interface UserDao {
public User queryUserByUsername(String username);
}
public interface RoleDao {
public Set<String> queryRoleNamesByUsername(String username);
}
public interface PermissionDao {
public Set<String> queryPermissionsByUsername(String username);
}
<?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.qfedu.shiro4.dao.UserDao">
<resultMap id="userMap" type="User">
<id column="user_id" property="userId"></id>
<result column="username" property="userName"/>
<result column="password" property="userPwd"/>
<result column="password_salt" property="pwdSalt"/>
</resultMap>
<select id="queryUserByUsername" resultMap="userMap">
SELECT * FROM tb_users WHERE username=#{username}
</select>
</mapper>
<?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.qfedu.shiro4.dao.RoleDao">
<select id="queryRoleNamesByUsername" resultSets="java.util.Set" resultType="string">
select role_name from tb_users inner join tb_urs
on tb_users.id=tb_urs.uid inner join tb_roles
on tb_urs.rid=tb_roles.role_id
where tb_users.username=#{username}
</select>
</mapper>
<?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.qfedu.shiro4.dao.PermissionDao">
<select id="queryPermissionsByUsername" resultSets="java.util.Set" resultType="string">
select tb_permissions.permission_code from tb_users
inner join tb_urs on tb_users.id=tb_urs.uid
inner join tb_roles on tb_urs.rid=tb_roles.role_id
inner join tb_rps on tb_roles.role_id=tb_rps.rid
inner join tb_permissions on tb_rps.pid=tb_permissions.permission_id
where tb_users.username=#{username}
</select>
</mapper>
2.4配置shiro
package com.qfedu.shiro4.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//shiro方言
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
@Bean
public HashedCredentialsMatcher getHashedCredentialsMatcher(){
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//matcher就是用来指定加密规则
//加密方式
matcher.setHashAlgorithmName("md5");
//hash次数
matcher.setHashIterations(1);
return matcher;
}
@Bean
public MyRealm getMyRealm(HashedCredentialsMatcher matcher){
MyRealm myRealm=new MyRealm();
myRealm.setCredentialsMatcher(matcher);
return myRealm;
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm myRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
//过滤器就是shiro进行权限校验的核心,进行认证和授权是需要SecurityManager的
filter.setSecurityManager(securityManager);
/*设置shiro的拦截规则
anon 匿名用户可访问
authc 认证用户可访问
user 使用RemeberMe的用户可访问
perms 对应权限可访问
role 对应角色可访问
*/
Map<String,String> filterMap=new HashMap<>();
filterMap.put("/", "anon");
filterMap.put("/login.html", "anon");
filterMap.put("/regist.html", "anon");
filterMap.put("/user/login", "anon");
filterMap.put("user/regist", "anon");
filterMap.put("/static/**", "anon");
filterMap.put("/**", "authc");
filter.setFilterChainDefinitionMap(filterMap);
filter.setLoginUrl("/login.html");
//设置未授权访问的页面路径
filter.setUnauthorizedUrl("/login.html");
return filter;
}
}
自定义Realm
package com.qfedu.shiro4.config;
import com.qfedu.shiro4.beans.User;
import com.qfedu.shiro4.dao.PermissionDao;
import com.qfedu.shiro4.dao.RoleDao;
import com.qfedu.shiro4.dao.UserDao;
import org.apache.shiro.authc.*;
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;
/**
* 1.创建一个类继承AuthorizingRealm类(实现了Realm接口的类)
* 2.重写doGetAuthorizationInfo和doGetAuthenticationInfo方法
* 3.重写getName方法
*/
public class MyRealm extends AuthorizingRealm {
@Resource
private UserDao userDao;
@Resource
private RoleDao roleDao;
@Resource
private PermissionDao permissionDao;
@Override
public String getName(){
return "myRealm";
}
/*获取授权数据*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.iterator().next();
Set<String> roleNames = roleDao.queryRoleNamesByUsername(username);
Set<String> ps = permissionDao.queryPermissionsByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roleNames);
info.setStringPermissions(ps);
return info;
}
/*获取认证数据*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//参数authenticationToken就是传递的 subject.login(token)
UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
User user = userDao.queryUserByUsername(username);
// AuthenticationInfo info=new SimpleAuthenticationInfo(
// username,
// user.getUserPwd(),
// getName()
// );
//如果数据库中用户密码是加了盐的
AuthenticationInfo info=new SimpleAuthenticationInfo(
username,
user.getUserPwd(),
ByteSource.Util.bytes(user.getPwdSalt()),
getName()
);
return info;
}
}
加密处理
@RequestMapping("/regist")
public String regist(String username,String userPwd){
//注册时对密码加密处理
Md5Hash md5Hash = new Md5Hash(userPwd);
System.out.println(md5Hash.toHex());
//加盐加密
int salt=new Random().nextInt(9999);
Md5Hash md5Hash1 = new Md5Hash(userPwd,salt+"");
//加盐加密加多次hash
Md5Hash md5Hash2 = new Md5Hash(userPwd,salt+"",3);
SimpleHash hash = new SimpleHash("md5", userPwd, salt, 3);
return "login";
}