spring security如何使用sec:authorize="hasAnyAuthority('PRODUCT_DELETE')"标签 及其在方法上使用权限注解

废话不多说,直接上代码,

第一
首先写一个类继承WebSecurityConfigurerAdapter
我只从代码中粘贴了一部分,
Configuration注解的作用,意思将给类交给spring容器管理(也可以说是被实例化)
EnableWebSecurity的作用,开启spring security过滤器链
EnableGlobalMethodSecurity ,开启权限注解,首先加上此注解,我们的标签及其权限注解才可以使用

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启权限注解,默认是关闭的
public class SecurityConfig extends WebSecurityConfigurerAdapter {

第二
需要在该类中注入自定义PermissionEvaluator,注意我在这里,自定义的类名叫做UserPermissionEvaluator

/**
     * 注入自定义PermissionEvaluator
     */
    @Bean
    public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler(){
        DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
        handler.setPermissionEvaluator(new UserPermissionEvaluator());
        return handler;
    }

第三

我们需要写一个类实现PermissionEvaluator接口,并且实现hasPermission方法
直接上代码

package com.sans.security;

import com.sans.core.entity.SysMenuEntity;
import com.sans.core.service.SysUserService;
import com.sans.security.entity.SelfUserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Component
public class UserPermissionEvaluator implements PermissionEvaluator {

    Logger logger=LoggerFactory.getLogger(UserPermissionEvaluator.class);

    @Autowired
    private SysUserService sysUserService;
    /**
     * hasPermission鉴权方法
     * 这里仅仅判断PreAuthorize注解中的权限表达式
     * 实际中可以根据业务需求设计数据库通过targetUrl和permission做更复杂鉴权
     * 当然targetUrl不一定是URL可以是数据Id还可以是管理员标识等,这里根据需求自行设计
     * @Author Sans
     * @CreateTime 2019/10/6 18:25
     * @Param  authentication  用户身份(在使用hasPermission表达式时Authentication参数默认会自动带上)
     * @Param  targetUrl  请求路径
     * @Param  permission 请求路径权限
     * @Return boolean 是否通过
     */
    @Override
    public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {

        logger.info("进来了!!!");
        logger.info("permission:{}",permission);

        // 获取用户信息
        SelfUserEntity selfUserEntity =(SelfUserEntity) authentication.getPrincipal();
        // 查询用户权限(这里可以将权限放入缓存中提升效率)
        Set<String> permissions = new HashSet<>();
        List<SysMenuEntity> sysMenuEntityList = sysUserService.selectSysMenuByUserId(selfUserEntity.getUserId());
        for (SysMenuEntity sysMenuEntity:sysMenuEntityList) {
            permissions.add(sysMenuEntity.getPermission());
        }
        // 权限对比
        if (permissions.contains(permission.toString())){
            return true;
        }
        return false;
    }
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

在这里我们就可以使用页面的标签及其方法上的注解
直接上代码

<div sec:authorize="hasPermission('/product/list','product:list')">
    <a href="/product/list">商品查询</a><br/>
</div>


@PreAuthorize("hasPermission('/product/list','product:list')")
    @RequestMapping(value = "/list")
    public String list() {
        return "product/list";
    }

这里有两个参数,我们说明一下什么意思。
第一个 资源URL(即请求路径)
第二个 对应的权限

以后会为大家介绍 没有赋予权限该如何处理
当然没有赋予权限的话,页面会出现

在这里插入图片描述

Forbidden 禁止的意思 403指未授权
控制台也不会报错,其实这个问题是否解决,个人感觉无所谓。只要不让用户做到非法请求的目的就行。。。

这辈子坚持与不坚持都不可怕,怕的是独自走在坚持的道路上。。。

欢迎加入技术群聊
在这里插入图片描述

发布了58 篇原创文章 · 获赞 8 · 访问量 14万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览