shiro实现加载数据库,使用资源菜单进行认证和授权操作

一.概述

说明:本次操作是在上一篇的基础上进行的授权操作。

https://www.bilibili.com/video/BV1uz4y197Zm?p=1

在菜单权限表中,admin具有id=2的菜单权限;ljf具有id=1,id=3的菜单权限,如下图

也就是说admin能访问所有模块的权限;ljf具有只能访问订单管理下的添加权限。

参考资料:

https://www.bilibili.com/video/BV1uz4y197Zm?p=1 

 

二.项目操作

2.1 配置userDao层

package com.shiro.ljf.demo.sptshirodemo.dao;

import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserDao {
    //注册数据
    public void addData(User user);
    //根据用户名查询用户
    public User findByUserName(String userName);
    //根据用户名查询所有角色
    User findRolesByUserName(String username);
    //根据角色id查询权限集合
    List<MenuPerms> findPermsByRoleId(String id);
}

2.2 配置service层 

package com.shiro.ljf.demo.sptshirodemo.service;

import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;

import java.util.List;

public interface UserService {
    //注册用户方法
    void register(User user);
    //查找用户名
    public User findByUserName(String username);
    //根据用户名查询所有角色
    User findRolesByUserName(String username);

    //根据角色id查询权限集合
    List<MenuPerms> findPermsByRoleId(String id);
}

2.3 mapper层

    <!--通过角色id查询权限菜单  -->
    <select id="findPermsByRoleId" parameterType="String" resultType="com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms">
      SELECT p.id,p.NAME,p.url,r.NAME
      FROM t_role r
      LEFT JOIN t_role_menu_perms rp
      ON r.id=rp.roleid
      LEFT JOIN t_menu_perms p ON rp.permsid=p.id
      WHERE r.id=#{id}
    </select>

2.4 controller层

package com.shiro.ljf.demo.sptshirodemo.controller;

import com.shiro.ljf.demo.sptshirodemo.entity.User;
import com.shiro.ljf.demo.sptshirodemo.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

/**
 * @ClassName: UserLoginController
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2020/10/29 08:13:50 
 * @Version: V1.0
 **/
@Controller
@RequestMapping("user")
public class UserLoginController {
    @Autowired
    private UserService userService;
    /**
     * 用来处理身份认证
     *
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("login")
    public String login(String username, String password, String code, HttpSession session, Model model) {
        try {
            System.out.println("进入login的登录方法====");
            //获取主体对象
            Subject subject = SecurityUtils.getSubject();
            //当执行这个login的方法,就会触发在自定义的CustomerRealm的AuthenticationInfo的方法
            subject.login(new UsernamePasswordToken(username, password));//!!!!
            return "redirect:/index.jsp";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误!");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误!");
            System.out.println("密码错误!");
            model.addAttribute("error","密码错误");
            return "login";
        }catch (Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        System.out.println("登录页面");
        return "redirect:/login.jsp";
    }

    /**
     * 退出登录
     */
    @RequestMapping("logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();//退出用户
        return "redirect:/login.jsp";
    }
    /**
     * 用户注册
     */
    @RequestMapping("register")
    public String register(User user) {
        try {
            System.out.println("进入userController 层了:!!!!!");
            if(user!=null&&user.getPassword()!=null){
                System.out.println("user的信息不为null:");
                userService.register(user);
                return "redirect:/login.jsp";
            }
            return "redirect:/register.jsp";
        }catch (Exception e){
            e.printStackTrace();
            return "redirect:/register.jsp";
        }
    }
    /**
     * work
     */
    @RequestMapping("work")
    public String work() {
        try {
            System.out.println("进入userController 层了work:!!!!!");

                return "redirect:/order.jsp";
        }catch (Exception e){
            e.printStackTrace();
            return "redirect:/register.jsp";
        }
    }
}

2.5 自定义reaml

package com.shiro.ljf.demo.sptshirodemo.shiro;

import com.shiro.ljf.demo.sptshirodemo.entity.MenuPerms;
import com.shiro.ljf.demo.sptshirodemo.entity.User;
import com.shiro.ljf.demo.sptshirodemo.service.UserService;
import com.shiro.ljf.demo.sptshirodemo.utils.ApplicationContextUtils;
import com.shiro.ljf.demo.sptshirodemo.utils.MyByteSource;
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 org.apache.shiro.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @ClassName: CustomerRealm
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2020/10/28 15:17:48 
 * @Version: V1.0
 **/
public class CustomerRealm extends AuthorizingRealm {
    /**
     * @author liujianfu
     * @description    授权方法
     * @date 2020/10/28 16:54
     * @return org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("进入授权部分======:");
        //获取身份信息
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println("调用授权验证: "+primaryPrincipal);
        /**
         if("ljf".equals(primaryPrincipal)){//登录的用户ljf,具有以下角色
         //角色的授权
         SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
         simpleAuthorizationInfo.addRole("admin");
         simpleAuthorizationInfo.addRole("guest");
         //权限字符串的授权
         simpleAuthorizationInfo.addStringPermission("haha:add:01");
         simpleAuthorizationInfo.addStringPermission("haha:update:02");
         return simpleAuthorizationInfo;
         }
         **/
        //根据主身份信息获取角色 和 权限信息
        UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
        User user = userService.findRolesByUserName(primaryPrincipal);
        //授权角色信息
        if(!CollectionUtils.isEmpty(user.getRoles())){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            user.getRoles().forEach(role->{
                simpleAuthorizationInfo.addRole(role.getName());
                //权限信息
                List<MenuPerms> perms = userService.findPermsByRoleId(role.getId());
                if(!CollectionUtils.isEmpty(perms)){
                    perms.forEach(perm->{
                        simpleAuthorizationInfo.addStringPermission(perm.getName());
                    });
                }
            });
            return simpleAuthorizationInfo;
        }
        return null;
    }

    /**
   * @author liujianfu
   * @description
   * @date 2020/10/28 16:54
   * @return org.apache.shiro.authc.AuthenticationInfo
   */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("============================================进入认证方法==================");
        /**      写死的部分
        //获取身份信息
        String primaryPrincipal = (String) authenticationToken.getPrincipal();
        System.out.println("调用验证: "+primaryPrincipal);
        //根据主身份信息获取角色 和 权限信息
        if("admin".equals(primaryPrincipal)) {
            System.out.println("this name:"+this.getName());
            return new SimpleAuthenticationInfo(primaryPrincipal,"123",this.getName());
        }

        return null;
         **/

        //根据身份信息   ,动态从数据库中加载数据
        String principal = (String) authenticationToken.getPrincipal();
        //在工厂中获取service对象
        UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
        User user = userService.findByUserName(principal);
        if(!ObjectUtils.isEmpty(user)){
            //设置用户名,密码,随机盐
            return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),
                    new MyByteSource(user.getSalt()),
                    this.getName());
        }
        return null;
    }

}

三 演示操作

1.使用admin 操作

1.输入地址

2.登录界面

 

3.主界面

3.2 通过ljf普通用户

1.输入地址

2.登录界面

3.主界面

结论:实现了不同用户所属不通角色,操作不同的权限资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值