springsecurity实现数据库动态加载资源鉴权规则以及权限表达式

1:在springsecurity的配置文件中添加配制

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().frameOptions().sameOrigin();
        //http.csrf().disable().cors().disable().headers().disable();
        http.authorizeRequests().antMatchers("/", "/index", "/index.html",
                "/toLoginPage").permitAll()

                //.antMatchers("/static/**").permitAll()
//  这个配置就是告诉springsecurity,鉴权规则通过数据库动态加载
.anyRequest().access("@myRbacAuthention.hasPermission(request,authentication)")
                /*.antMatchers("/vip1").hasRole("VIP1")
                .antMatchers("/vip2").hasRole("VIP2")
                .antMatchers("/vip3").hasRole("VIP3")*/;
        // 开启表单认证
        http.formLogin().loginProcessingUrl("/login").loginPage("/toLoginPage")
                // 成功和失败的处理器
                .successHandler(mySavedRequestAwareAuthenticationSuccessHandler)
                .failureHandler(mySimpleUrlAuthenticationFailureHandler);

        // 开启记住我,60秒
        http.rememberMe().rememberMeParameter("rememberMe").tokenValiditySeconds(60);

        // 开启注销
        http.logout().logoutSuccessUrl("/");

        // 处理登出的404错误!springsecurity的csrf(跨站请求伪造)保护
        http.csrf().disable();

        // 一个账户只能一个账号登陆,maxSessionsPreventsLogin(false)设置为false,标识第一个账号登陆后,
        // 同一个账号还可以在其他地方登陆。只是将第一个挤下去,如果设置为true,则同一个账号就不能再次登陆了

        http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false)
                .expiredSessionStrategy(new MySessionInfomantion());
    }

2:自定义一个数据库加载资源鉴权的类

就是加载数据库中查询当前用户所有拥有的权限,然后和当前请求的资源进行比对,成功就返回true,否则就返回false

package com.itgo.springboot.springsecurity.config;

import com.itgo.springboot.springsecurity.mapper.SysUserMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @Description: 自定义的权限表达式
 * @auther: libiao
 * @Email: libiao@163.com
 * @Date: 2020-6-21 14:51
 * @Copyright: (c) 2019-2022  XXXX公司
 */
@Component("myRbacAuthention")
public class MyRbacAuthention {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Resource
    private SysUserMapper sysUserMapper;
    /**
     * @Description: 判断当前用户是否存在某种权限
     * @author libiao
     * @Date 2020-6-21 14:52
     * @Param
     * @return
     **/
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {

        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails) {
            String username = ((UserDetails) principal).getUsername();
            // 通过用户名查询这个用户的所有权限
            List<String> permissions = sysUserMapper.getAllPermissionByUesrName(username);
            return permissions.stream().anyMatch(
                    url -> antPathMatcher.match(url, request.getRequestURI())
            );
        }
        return false;
    }
}

3:权限表达式

如果需要在方法上做权限表达式,需要配置注解,开启
在springsecurity的配置类中,开启注解
@EnableGlobalMethodSecurity(prePostEnabled = true)// 默认是false

package com.libiao.basicserver.service;

import com.libiao.basicserver.model.Person;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static org.springframework.security.core.context.SecurityContextHolder.getContext;

@Service
public class MethodelService {
// 在执行方法之前判断当前用户是否存在admin这个角色
    @PreAuthorize("hasRole('admin')")
    public List<Person> findAll(){
        return null;
    }

// 在执行方法后,判断返回值
    @PostAuthorize("returnObject.name == authentication.name")
    public Person findOne(){
        String authName =
                getContext().getAuthentication().getName();
        System.out.println(authName);
        return new Person("admin");
    }
// 过滤,执行方法之前,过滤掉,不满足要求的参数
    @PreFilter(filterTarget="ids", value="filterObject%2==0")
    public void delete(List<Integer> ids, List<String> usernames) {
        System.out.println();
    }

// 执行方法后,过滤掉不满足要求的返回值
    @PostFilter("filterObject.name == authentication.name")
    public List<Person> findAllPD(){

        List<Person> list = new ArrayList<>();
        list.add(new Person("kobe"));
        list.add(new Person("admin"));

        return list;
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值