SpringBoot与Shrio(三)授权部分

本文详细介绍了使用Shiro进行权限管理的数据库设计,包括用户、角色和权限的多对多关系。通过User、Role和Permission实体类,以及对应的Mapper和服务,实现了用户角色查询和权限集合获取。在自定义Realm中,实现了授权和认证逻辑,对用户角色信息和权限字符串进行了控制。此外,还提供了Controller测试用例,展示了如何运用角色和权限控制访问。

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

简易版数据库设计

关于权限的数据库设计:
1.用户与角色绑定,角色与权限绑定,权限与资源绑定
2.不想基于权限字符串管理:用户与角色绑定
3.不想基于角色管理:用户与权限绑定
4.不想让角色和权限关联:用户与角色绑定,用户与权限绑定

这里使用第一种,用户与角色多对多,角色与权限多对多,权限与资源一对一

用户表
user在这里插入图片描述

角色表
角色在这里插入图片描述

权限表
权限在这里插入图片描述

用户角色表
用户角色在这里插入图片描述

角色权限表
角色权限在这里插入图片描述

实体类User

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private long id;
    private String name;
    private String pass;
    private String salt;

    //用户角色
    private List<Role> roles;
}

mapper

//根据用户名查角色
    User findRolesByName(String name);
	<select id="findRolesByName" resultMap="userMap" >
        SELECT
            u.id,
            u. NAME,
            r.id rid,
            r.`name` rname
        FROM
            test u
        LEFT JOIN t_user_role ur ON u.id = ur.userid
        LEFT JOIN t_role r ON r.id = ur.roleid
        WHERE
            u. name = #{name}
    </select>
    
    <resultMap id="userMap" type="cn.xx.shiroboot.entity.User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>

        <collection property="roles" javaType="list" ofType="cn.xx.shiroboot.entity.Role">
            <id column="rid" property="name"/>
            <result column="rname" property="name"></result>
        </collection>
    </resultMap>

service略

实体类Role

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {
    private long id;
    private String name;

    //权限集合
    private List<Per> pers;
}

mapper

 //根据角色id查权限集合
    List<Per> findPersByRoleId(long id);
	<select id="findPersByRoleId" resultType="cn.xx.shiroboot.entity.Role">
        SELECT
            *
        FROM
            role r
        LEFT JOIN t_role_per rp ON r.id = rp.roleid
        LEFT JOIN t_per p ON p.id = rp.perid
        WHERE
            r.id = #{id}
    </select>

service略

全部的自定义realm(授权角色信息和字符串权限控制)

public class CustomerRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取身份信息
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        //根据身份信息获取角色和授权信息
        User user = userService.findRolesByName(primaryPrincipal);
        //授权角色信息
        if (!CollectionUtils.isEmpty(user.getRoles())){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //增加角色信息
            user.getRoles().forEach(role->{
                simpleAuthorizationInfo.addRole(role.getName());

                //权限信息
                List<Per> pers = roleService.findPersByRoleId(role.getId());
                if (!CollectionUtils.isEmpty(pers)){
                    pers.forEach(per->{
                        simpleAuthorizationInfo.addStringPermission(per.getName());
                    });
                }
            });

            return simpleAuthorizationInfo;
        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //在工厂中获取service对象
        /*UserService userService = (UserService) ApplicationContextUtil.getBean("userService");*/
        System.out.println(userService);
        User user = userService.findByName(principal);

        if (!ObjectUtils.isEmpty(user)){
            return new SimpleAuthenticationInfo(user.getName(),user.getPass(), ByteSource.Util.bytes(user.getSalt()),getName());
        }

        return null;
    }
}

controller测试

 /**
     * 权限控制
     */
    @RequestMapping("test")
    //@RequiresRoles("admin")
    @RequiresRoles(value = {"admin","user"})   //用来判断角色,同时具有
    //@RequiresPermissions("user:update:shop") //用来判断权限字符串
    public String test(){
       /* //获取主体对象
        Subject subject = SecurityUtils.getSubject();

        //代码方式控制
        if (subject.hasRole("admin")){
            System.out.println("进去了");
        }else {
            System.out.println("没进去");
        }

        //权限字符串控制
        if (subject.isPermitted("user:update:shop")){
            System.out.println("进去了");
        }else{
            System.out.println("没进去");
        }*/

        return "redirect:/index.jsp";
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值