springboot——shiro

参考:https://how2j.cn/k/shiro/shiro-plan/1732.html#nowhere

代码下载

链接:https://pan.baidu.com/s/1lbQRPRaSedPQwXK-sbN66w
提取码:k2pa

1.Shiro介绍

一个简洁的网络安全框架

2.shiro 如何进行加密

MD5加密算法

项目中对于密码通常采用非对称加密,什么是非对称呢?就是不可逆的,而 md5 就是这样一个算法。
简单测试一下:

public static void main(String[] args) {
        String password = "123";
        String encodedPassword = new Md5Hash(password).toString();
        System.out.println(encodedPassword);
}

如果单纯的使用MD5加密算法也有缺陷,当密码太简单时可能会被穷举破解。
盐就是一个随机数,我在密码后加上一个一个随机字符串,即使相同的密码在数据库里的存储也不同,这就增大了安全性。盐也会保存在数据库中,每个用户的都不一样。

3.springboot 整合 shiro

1.数据库准备

#
# Structure for table "permission"
#

DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `desc_` varchar(100) DEFAULT NULL,
  `url` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

#
# Data for table "permission"
#

INSERT INTO `permission` VALUES (1,'addProduct','增加产品','/addProduct'),(2,'deleteProduct','删除产品','/deleteProduct'),(3,'editeProduct','编辑产品','/editeProduct'),(4,'updateProduct','修改产品','/updateProduct'),(5,'listProduct','查看产品','/listProduct'),(6,'addOrder','增加订单','/addOrder'),(7,'deleteOrder','删除订单','/deleteOrder'),(8,'editeOrder','编辑订单','/editeOrder'),(9,'updateOrder','修改订单','/updateOrder'),(10,'listOrder','查看订单','/listOrder');

#
# Structure for table "role"
#

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `desc_` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

#
# Data for table "role"
#

INSERT INTO `role` VALUES (1,'admin','超级管理员'),(2,'productManager','产品管理员'),(3,'orderManager','订单管理员');

#
# Structure for table "role_permission"
#

DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `rid` bigint(20) DEFAULT NULL,
  `pid` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8;

#
# Data for table "role_permission"
#

INSERT INTO `role_permission` VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4),(5,1,5),(6,1,6),(7,1,7),(8,1,8),(9,1,9),(10,1,10),(11,2,1),(12,2,2),(13,2,3),(14,2,4),(15,2,5),(50,3,10),(51,3,9),(52,3,8),(53,3,7),(54,3,6),(55,3,1),(56,5,11);

#
# Structure for table "user"
#

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `salt` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

#
# Data for table "user"
#

INSERT INTO `user` VALUES (1,'zhang3','a7d59dfc5332749cb801f86a24f5f590','e5ykFiNwShfCXvBRPr3wXg=='),(2,'li4','43e28304197b9216e45ab1ce8dac831b','jPz19y7arvYIGhuUjsb6sQ==');

#
# Structure for table "user_role"
#

DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `uid` bigint(20) DEFAULT NULL,
  `rid` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;

#
# Data for table "user_role"
#

INSERT INTO `user_role` VALUES (43,2,2),(45,1,1);

2.项目结构

在这里插入图片描述

3.基于url配置权限

PermissionService.java

public interface PermissionService {
    public Set<String> listPermissions(String userName);
 
    public List<Permission> list();
 
    public void add(Permission permission);
 
    public void delete(Long id);
 
    public Permission get(Long id);
 
    public void update(Permission permission);
 
    public List<Permission> list(Role role);
 	/*needInterceptor 判断是否要进行拦截*/
    public boolean needInterceptor(String requestURI);
	 /*listPermissionURLs(User user) 用来获取某个用户所拥有的权限地址集合*/
    public Set<String> listPermissionURLs(String userName);
}

PermissionServiceImpl.java:

@Service
public class PermissionServiceImpl implements PermissionService {
 
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;
    @Autowired
    RolePermissionMapper rolePermissionMapper;
 
    @Override
    public Set<String> listPermissions(String userName) {
        Set<String> result = new HashSet<>();
        List<Role> roles = roleService.listRoles(userName);
 
        List<RolePermission> rolePermissions = new ArrayList<>();
 
        for (Role role : roles) {
            RolePermissionExample example = new RolePermissionExample();
            example.createCriteria().andRidEqualTo(role.getId());
            List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
            rolePermissions.addAll(rps);
        }
 
        for (RolePermission rolePermission : rolePermissions) {
            Permission p = permissionMapper.selectByPrimaryKey(rolePermission.getPid());
            result.add(p.getName());
        }
 
        return result;
    }
 
    @Override
    public void add(Permission u) {
        permissionMapper.insert(u);
    }
 
    @Override
    public void delete(Long id) {
        permissionMapper.deleteByPrimaryKey(id);
    }
 
    @Override
    public void update(Permission u) {
        permissionMapper.updateByPrimaryKeySelective(u);
    }
 
    @Override
    public Permission get(Long id) {
        return permissionMapper.selectByPrimaryKey(id);
    }
 
    @Override
    public List<Permission> list() {
        PermissionExample example = new PermissionExample();
        example.setOrderByClause("id desc");
        return permissionMapper.selectByExample(example);
 
    }
 
    @Override
    public List<Permission> list(Role role) {
        List<Permission> result = new ArrayList<>();
        RolePermissionExample example = new RolePermissionExample();
        example.createCriteria().andRidEqualTo(role.getId());
        List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
        for (RolePermission rolePermission : rps) {
            result.add(permissionMapper.selectByPrimaryKey(rolePermission.getPid()));
        }
 
        return result;
    }
 
	@Override
	public boolean needInterceptor(String requestURI) {
		//获取所有的权限
		List<Permission> ps = list();
		//权限中的url与参数对照
		for (Permission p : ps) {
			//匹配成功说明该requestURI只有当用户拥有该权限时才可进入
			if (p.getUrl().equals(requestURI))
				//return true还是false看需求
				return true;
		}
		return false;
	}
 	/*用来获取某个用户所拥有的权限地址集合*/
    @Override
    public Set<String> listPermissionURLs(String userName) {
        Set<String> result = new HashSet<>();
        List<Role> roles = roleService.listRoles(userName);
 
        List<RolePermission> rolePermissions = new ArrayList<>();
 
        for (Role role : roles) {
            RolePermissionExample example = new RolePermissionExample();
            example.createCriteria().andRidEqualTo(role.getId());
            List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
            rolePermissions.addAll(rps);
        }
 
        for (RolePermission rolePermission : rolePermissions) {
            Permission p = permissionMapper.selectByPrimaryKey(rolePermission.getPid());
            result.add(p.getUrl());
        }
 
        return result;
    }
}

URLPathMatchingFilter(内置过滤器):

public class URLPathMatchingFilter extends PathMatchingFilter {
    @Autowired
    PermissionService permissionService;
    @Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
            throws Exception {
        String requestURI = getPathWithinApplication(request);
 
        System.out.println("requestURI:" + requestURI);
 
        Subject subject = SecurityUtils.getSubject();
        // 如果没有登录,就跳转到登录页面
        if (!subject.isAuthenticated()) {
            WebUtils.issueRedirect(request, response, "/login");
            return false;
        }
 
        // 看看这个路径权限里有没有维护,如果没有维护,一律放行(也可以改为一律不放行)
        boolean needInterceptor = permissionService.needInterceptor(requestURI);
        if (!needInterceptor) {
            return true;
        } else {
            boolean hasPermission = false;
            String userName = subject.getPrincipal().toString();
            Set<String> permissionUrls = permissionService.listPermissionURLs(userName);
            for (String url : permissionUrls) {
                // 这就表示当前用户有这个权限
                if (url.equals(requestURI)) {
                    hasPermission = true;
                    break;
                }
            }
 
            if (hasPermission)
                return true;
            else {
                UnauthorizedException ex = new UnauthorizedException("当前用户没有访问路径 " + requestURI + " 的权限");
 
                subject.getSession().setAttribute("ex", ex);
 
                WebUtils.issueRedirect(request, response, "/unauthorized");
                return false;
            }
        }
    }
}

后台代码执行步骤:

  1. 进入登录界面,该界面在配置文件中配置到:不需任何权限可访问
  2. 登录,登录方法中有:subject.login(token);
  3. 执行DatabaseRealm中的doGetAuthenticationInfo校验账号密码
  4. 如果校验成功,跳转,失败返回登录界面
  5. 点击页面任一链接。URLPathMatchingFilter执行PermissionServiceImpl中的needInterceptor
  6. 如果没规定要有权限要求,调整,如果有
  7. 执行PermissionServiceImpl中的listPermissionURLs,查看使用者的权限
  8. 有该权限,放行,没有则拦截。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值