springboot + springsecurity实现动态url细粒度权限认证

2022-08-10 14:19:55

谨记:Url表只储存受保护的资源,不在表里的资源说明不受保护,任何人都可以访问
1、MyFilterInvocationSecurityMetadataSource 类判断该访问路径是否被保护

@Component//用于设置受保护资源的权限信息的数据源publicclassMyFilterInvocationSecurityMetadataSourceimplementsFilterInvocationSecurityMetadataSource{@Beanpublic AntPathMatchergetAntPathMatcher(){returnnewAntPathMatcher();}@Autowired//获取数据库中的保存的url  Url表只储存受保护的资源,不在表里的资源说明不受保护,任何人都可以访问private RightsMapper rightsMapper;@Autowiredprivate AntPathMatcher antPathMatcher;@Override/*
     * @param 被调用的保护资源
     * @return 返回能够访问该保护资源的角色集合,如果没有,则应返回空集合。
     */public Collection<ConfigAttribute>getAttributes(Object object)throws IllegalArgumentException{
        FilterInvocation fi=(FilterInvocation) object;//获取用户请求的Url
        String url= fi.getRequestUrl();//先到数据库获取受权限控制的Url
        List<Rights> us= rightsMapper.queryAll();//用于储存用户请求的Url能够访问的角色
        Collection<ConfigAttribute> rs=newArrayList<ConfigAttribute>();for(Rights u:us){if(u.getUrl()!= null){//逐一判断用户请求的Url是否和数据库中受权限控制的Url有匹配的if(antPathMatcher.match(u.getUrl(), url)){//如果有则将可以访问该Url的角色储存到Collection<ConfigAttribute>
                    rs.add(rightsMapper.queryById(u.getId()));}}}if(rs.size()>0){return rs;}//没有匹配到,就说明此资源没有被控制,所有人都可以访问,返回null即可,返回null则不会进入之后的decide方法return null;}@Overridepublic Collection<ConfigAttribute>getAllConfigAttributes(){// TODO 自动生成的方法存根return null;}@Overridepublicbooleansupports(Class<?> clazz){// TODO 自动生成的方法存根return FilterInvocation.class.isAssignableFrom(clazz);}}

rights表中的部分内容:
表结构

在这里插入图片描述内容:
在这里插入图片描述
2、MyAccessDecisionManager 类判断该用户是否有权限访问

@Component//用于设置判断当前用户是否可以访问被保护资源的逻辑publicclassMyAccessDecisionManagerimplementsAccessDecisionManager{@Override/*
     * @param 请求该保护资源的用户对象
     * @param 被调用的保护资源
     * @param 有权限调用该资源的集合
     */publicvoiddecide(Authentication authentication, Object object,
                       Collection<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException{
        Iterator<ConfigAttribute> ite= configAttributes.iterator();//遍历configAttributes,查看当前用户是否有对应的权限访问该保护资源while(ite.hasNext()){
            ConfigAttribute ca= ite.next();
            String needRole= ca.getAttribute();for(GrantedAuthority ga: authentication.getAuthorities()){if(ga.getAuthority().equals(needRole)){// 匹配到有对应角色,则允许通过return;}}}// 该url有配置权限,但是当前登录用户没有匹配到对应权限,则禁止访问thrownewAccessDeniedException("not allow");}@Overridepublicbooleansupports(ConfigAttribute attribute){returntrue;}@Overridepublicbooleansupports(Class<?> clazz){returntrue;}}

3、在SecurityConfig 类中配置说明

@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled=true)publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Autowired
    MyUserDetailsService myUserDetailsService;@Autowiredprivate SendSmsSecurityConfig sendSmsSecurityConfig;@Autowiredprivate MyAccessDecisionManager myAccessDecisionManager;@Autowiredprivate MyFilterInvocationSecurityMetadataSource myFilterInvocationSecurityMetadataSource;//加密机制@Beanpublic PasswordEncoderpasswordEncoder(){return NoOpPasswordEncoder.getInstance();// 不加密}//认证@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throws Exception{
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotectedvoidconfigure(HttpSecurity http)throws Exception{
        http.authorizeRequests()//对请求授权.antMatchers("/**").permitAll().anyRequest()//任何请求.authenticated()//登录后访问.withObjectPostProcessor(newObjectPostProcessor<FilterSecurityInterceptor>(){@Overridepublic<OextendsFilterSecurityInterceptor> OpostProcess(
                                    O fsi){
                                fsi.setSecurityMetadataSource(myFilterInvocationSecurityMetadataSource);
                                fsi.setAccessDecisionManager(myAccessDecisionManager);return fsi;}}).and().csrf().disable();}}

配置如下代码:
在这里插入图片描述至此完成所有配置!!!

  • 作者:佛说"獨"
  • 原文链接:https://blog.csdn.net/weixin_45498999/article/details/107386982
    更新时间:2022-08-10 14:19:55