最近学习若依框架,里面的权限注解涉及到了SpEL表达式 @PreAuthorize("@ss.hasPermi('system:user:list')"),若依项目中用的是自己写的方法进行权限处理, 也可以只用security 来实现权限逻辑代码,下面写如何用security 实现。

security中  @PreAuthorize("hasPermission(Object target, Object permission)")  的hasPermission方法,是通过PermissionEvaluator实现,默认继承类是DenyAllPermissionEvaluator,所有方法返回false,所以注解后的结果只有拒绝权限;所以继承PermissionEvaluator重写hasPermission即可。

逻辑如下:

1、securityConfig文件上加入注解@EnableMethodSecurity,且引入自定义评估器:CustomPermissionEvaluator

2、编写CustomPermissionEvaluator文件

:security 6.2.1 中 EnableGlobalMethodSecurity 已弃用,改使用 EnableMethodSecurity 且prePostEnabled为ture,只需添加注解@EnableMethodSecurity 即可

package com.example.securityDemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @description: security配置类
 * @author: mml
 * @create: 2024/01/26
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    // 引入自定义评估器
    @Bean
    static MethodSecurityExpressionHandler methodSecurityExpressionHandler(CustomPermissionEvaluator permissionEvaluator) {
        DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
        handler.setPermissionEvaluator(permissionEvaluator);
        return handler;
    }

    @Bean
    UserDetailsService userDetailsService(){
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("mml")
                .password("123")
                .roles("USER")
                .authorities("system:user:update","system:user:list")
                .build();
        return new InMemoryUserDetailsManager(user);
    }


    /**
     * 是Spring Security 过滤器链,Spring Security 中的所有功能都是通过这个链来提供的
     * @date 2024/1/26
     */
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        // 拦截所有请求,但是不经过任何过滤器
//        return new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"));
        httpSecurity.authorizeHttpRequests(p -> p.anyRequest().authenticated())
                .csrf(c -> c.disable())
                .formLogin((form) -> form
                        .loginPage("/login")
                        .permitAll());
        return httpSecurity.build();

    }


}

自定义评估器代码

import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.io.Serializable;
import java.util.Collection;

/**
 * @description: 自定义权限评估器
 * @author: mml
 * @create: 2024/02/17
 */
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        // 获取当前用户的角色
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        for (GrantedAuthority authority : authorities) {
            // 权限判断
            if (antPathMatcher.match(authority.getAuthority(), (String) permission)){
                // 说明有权限
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}

接口层:

@RestController
public class UserController {

    @RequestMapping("/list")
    @PreAuthorize("hasPermission('/list','system:user:list')")
    public String list() {
        return "get list ";
    }

    @RequestMapping("/add")
    @PreAuthorize("hasPermission('/add','system:user:add')")
    public String add() {
        return "post add ";
    }
}

可以使用postman测试

测试结果如下:

list-有权限

add 方法-没有权限

security参考链接:方法安全 :: Spring Security

Logo

快速构建 Web 应用程序

更多推荐