角色认证功能

本文详细介绍了如何使用Shiro进行角色认证,包括授权过程、后端接口服务注解的使用,以及提供了一步步实现授权功能的示例,涵盖了从数据库表设计到各个组件如UserMapper、UserService、UserServiceImpl、MyController和MyRealm的配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、授权

用户登录后,需要验证是否具有指定角色指定权限。Shiro也提供了方便的工具进行判断。

这个工具就是Realm的doGetAuthorizationInfo方法进行判断。触发权限判断的有两种

  • 在页面中通过shiro:****属性判断
  • 在接口服务中通过注解@Requires****进行判断

二、后端接口服务注解

通过给接口服务方法添加注解可以实现权限校验,可以加在控制器方法上,也可以加在业务方法上,一般加在控制器方法上。常用注解如下:

@RequiresAuthentication
验证用户是否登录,等同于方法subject.isAuthenticated()

@RequiresUser
验证用户是否被记忆;
登录认证成功subiect.isAuthenticated()为true
登录后被记忆subject.isRemembered()为true

@RequiresGuest
验证是否是一个guest的请求,是否是游客的请求
此时subject.getPrincipal()为null

@RequiresRoles
验证subject是否有相应角色,有角色访问方法,没有则会抛出异常AuthorizationException。
例如:@RequiresRoles( “aRoleName”)
void someMethod();
只有subject有aRoleName角色才能访问方法someMethod()

@RequiresPermissions
验证subject是否有相应权限,有权限访问方法,没有则会抛出异常AuthorizationException。
例如: @RequiresPermissions(“file:read”,“wite:aFile.txt”)
void someMethod() ;
subject必须同时含有file:read和wite:aFile.txt权限才能访问方法someMethod()

三、示例

3.1、沿用上一篇博客项目

3.2、添加数据库表

USE shirodb

CREATE TABLE role(
	id BIGINT(20) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(30) DEFAULT NULL,
	`desc` VARCHAR(50) DEFAULT NULL,
	`realname` VARCHAR(20) DEFAULT NULL,
	PRIMARY KEY(id)
)ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

INSERT INTO role VALUES(1,'admin','所有权限','管理员');
INSERT INTO role VALUES(2,'userMag','用户管理权限','用户管理');


CREATE TABLE role_user(
	id BIGINT(20) NOT NULL AUTO_INCREMENT,
	uid BIGINT(20) DEFAULT NULL,
	rid BIGINT(20) DEFAULT NULL,
	PRIMARY KEY(id)
)ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

在这里插入图片描述

3.3、在main.html添加测试授权链接

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Shiro登录认证后主页面</h1>
<br>
登录用户为:<span th:text="${session.user}"></span>
<br>
<a href="/logout">登出</a>
<br>
<a href="/myController/userLoginRoles">测试授权</a>
</body>
</html>

3.4、在UserMapper中添加根据用户名查询角色名的方法

package com.massimo.shiro.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.massimo.shiro.entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserMapper extends BaseMapper<User> {

    @Select("SELECT `name` FROM role WHERE id IN (\n" +
            "\tSELECT rid FROM `role_user` WHERE uid=(\n" +
            "\t\tSELECT id FROM `user` WHERE `name`=#{principal}\n" +
            "\t)\n" +
            ")")
    List<String> getUserRoleInfoMapper(@Param("principal")String principal);
}

3.5、UserService

package com.massimo.shiro.service;

import com.massimo.shiro.entity.User;

import java.util.List;

public interface UserService {
    //用户登录
    User getUserInfoByName(String name);
    //根据用户查询角色信息
    List<String> getUserRoleInfo(String principal);
}

3.6、UserServiceImpl

package com.massimo.shiro.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.massimo.shiro.entity.User;
import com.massimo.shiro.mapper.UserMapper;
import com.massimo.shiro.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User getUserInfoByName(String name) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name",name);
        User user =  userMapper.selectOne(wrapper);
        return user;
    }

    //根据用户查询角色信息
    @Override
    public List<String> getUserRoleInfo(String principal) {
        return userMapper.getUserRoleInfoMapper(principal);
    }
}

3.7、MyController

    //登录认证角色
    @RequiresRoles("admin")
    @GetMapping("userLoginRoles")
    @ResponseBody
    public String userLoginRoles(){
        System.out.println("登录验证角色");
        return "验证角色成功!";
    }

3.8、MyRealm

    //自定义授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("自定义授权方法!");
        //1.获取用户身份信息
        String principal = principalCollection.getPrimaryPrincipal().toString();
        //2.调用业务层获取用户的角色信息(从数据库)
        List<String> roles = userService.getUserRoleInfo(principal);
        System.out.println("当前用户角色信息" + roles);
        //3.创建对象,封装当前登录用户的角色、权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        //3.返回信息
        return info;
    }

3.9、项目结构

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值