电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

springboot+springsecurity如何實現動態url細粒度權限認證

瀏覽:81日期:2023-03-02 10:16:54

謹記:Url表只儲存受保護的資源,不在表里的資源說明不受保護,任何人都可以訪問

1、MyFilterInvocationSecurityMetadataSource 類判斷該訪問路徑是否被保護

@Component//用于設置受保護資源的權限信息的數據源public class MyFilterInvocationSecurityMetadataSource implementsFilterInvocationSecurityMetadataSource { @Bean public AntPathMatcher getAntPathMatcher(){return new AntPathMatcher(); }@Autowired //獲取數據庫中的保存的url Url表只儲存受保護的資源,不在表里的資源說明不受保護,任何人都可以訪問 private RightsMapper rightsMapper; @Autowired private AntPathMatcher antPathMatcher; @Override /* * @param 被調用的保護資源 * @return 返回能夠訪問該保護資源的角色集合,如果沒有,則應返回空集合。 */ public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {FilterInvocation fi = (FilterInvocation) object;//獲取用戶請求的UrlString url = fi.getRequestUrl();//先到數據庫獲取受權限控制的UrlList<Rights> us = rightsMapper.queryAll();//用于儲存用戶請求的Url能夠訪問的角色Collection<ConfigAttribute> rs=new ArrayList<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; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() {// TODO 自動生成的方法存根return null; } @Override public boolean supports(Class<?> clazz) {// TODO 自動生成的方法存根return FilterInvocation.class.isAssignableFrom(clazz); }}

rights表中的部分內容:

表結構

springboot+springsecurity如何實現動態url細粒度權限認證

內容:

springboot+springsecurity如何實現動態url細粒度權限認證

2、MyAccessDecisionManager 類判斷該用戶是否有權限訪問

@Component//用于設置判斷當前用戶是否可以訪問被保護資源的邏輯public class MyAccessDecisionManager implements AccessDecisionManager { @Override /* * @param 請求該保護資源的用戶對象 * @param 被調用的保護資源 * @param 有權限調用該資源的集合 */ public void decide(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有配置權限,但是當前登錄用戶沒有匹配到對應權限,則禁止訪問throw new AccessDeniedException('not allow'); } @Override public boolean supports(ConfigAttribute attribute) {return true; } @Override public boolean supports(Class<?> clazz) {return true; }}3、在SecurityConfig 類中配置說明

@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired MyUserDetailsService myUserDetailsService; @Autowired private SendSmsSecurityConfig sendSmsSecurityConfig; @Autowired private MyAccessDecisionManager myAccessDecisionManager; @Autowired private MyFilterInvocationSecurityMetadataSource myFilterInvocationSecurityMetadataSource; //加密機制 @Bean public PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance(); // 不加密 } //認證 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()//對請求授權.antMatchers('/**').permitAll().anyRequest()//任何請求.authenticated()//登錄后訪問.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { @Override public <O extends FilterSecurityInterceptor> O postProcess( O fsi) {fsi.setSecurityMetadataSource(myFilterInvocationSecurityMetadataSource);fsi.setAccessDecisionManager(myAccessDecisionManager);return fsi; }}).and().csrf().disable(); }}

配置如下代碼:

springboot+springsecurity如何實現動態url細粒度權限認證

至此完成所有配置!!!

SpringSecurity解決公共接口自定義權限驗證失效問題,和源碼分析背景:

自定義權限認證,一部分接口必須要有相應的角色權限,一部分接口面向所有訪問者,一部分接口任何人都不能訪問。但是在使用 SpringSecurity的過程中發現,框架會將沒有指定角色列表的URL資源直接放行,不做攔截。

用戶登錄認證成功后,攜帶Token訪問URL資源,spring security 根據Token(請求頭Authorization中)來分辨不同用戶。

用戶權限數據源是一個Map:以 URL資源為Key,以有權訪問的Key的角色列表為Value。

使用時發現當一個接口有Key,但是Value為空或null時,spring security 框架自動放行,導致了權限失效問題。

解決方法有兩種:

第一種方法:

默認rejectPublicInvocations為false。

對需要控制權限的URL資源添加標志,以防止roleList為空,跳過了權限驗證.

公共權限設置為null,不進行權限驗證

第二種方法:

配置rejectPublicInvocations為true

此后roleList為空,或者沒有找到URL資源時,都為拒絕訪問

需要控制權限的URL資源,即使對應角色為空,也會進行權限驗證

公共權限設置為所有角色和匿名角色,不進行權限驗證

package org.springframework.security.access.intercept;/** * 對安全對象(訪問請求+用戶主體)攔截的抽象類源碼 */public abstract class AbstractSecurityInterceptor implements InitializingBean, ApplicationEventPublisherAware, MessageSourceAware {// ... 其他方法省略protected InterceptorStatusToken beforeInvocation(Object object) {Assert.notNull(object, 'Object was null');final boolean debug = logger.isDebugEnabled();if (!getSecureObjectClass().isAssignableFrom(object.getClass())) {throw new IllegalArgumentException('Security invocation attempted for object '+ object.getClass().getName()+ ' but AbstractSecurityInterceptor only configured to support secure objects of type: '+ getSecureObjectClass());}// 從權限數據源獲取了當前 <URL資源> 對應的 <角色列表>Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object);// 框架在此處判斷URL資源對應的角色列表是否為空if (attributes == null || attributes.isEmpty()) {// rejectPublicInvocations默認為false // 可以配置為true,即角色列表為空的時候不進行放行if (rejectPublicInvocations) {throw new IllegalArgumentException('Secure object invocation '+ object+ ' was denied as public invocations are not allowed via this interceptor. '+ 'This indicates a configuration error because the '+ 'rejectPublicInvocations property is set to ’true’');}if (debug) {logger.debug('Public object - authentication not attempted');}publishEvent(new PublicInvocationEvent(object));return null; // no further work post-invocation}if (debug) {logger.debug('Secure object: ' + object + '; Attributes: ' + attributes);}// 如果當前用戶權限對象為nullif (SecurityContextHolder.getContext().getAuthentication() == null) {credentialsNotFound(messages.getMessage('AbstractSecurityInterceptor.authenticationNotFound','An Authentication object was not found in the SecurityContext'),object, attributes);}Authentication authenticated = authenticateIfRequired();// Attempt authorization,此處調用accessDecisionManager 進行鑒權try {this.accessDecisionManager.decide(authenticated, object, attributes);}catch (AccessDeniedException accessDeniedException) {publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated,accessDeniedException));throw accessDeniedException;}if (debug) {logger.debug('Authorization successful');}if (publishAuthorizationSuccess) {publishEvent(new AuthorizedEvent(object, attributes, authenticated));}// Attempt to run as a different user,這里可以另外配置或修改用戶的權限對象,特殊場景使用Authentication runAs = this.runAsManager.buildRunAs(authenticated, object,attributes);if (runAs == null) {if (debug) {logger.debug('RunAsManager did not change Authentication object');}// no further work post-invocationreturn new InterceptorStatusToken(SecurityContextHolder.getContext(), false,attributes, object);}else {if (debug) {logger.debug('Switching to RunAs Authentication: ' + runAs);}SecurityContext origCtx = SecurityContextHolder.getContext();SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());SecurityContextHolder.getContext().setAuthentication(runAs);// need to revert to token.Authenticated post-invocationreturn new InterceptorStatusToken(origCtx, true, attributes, object);}}// ... 其他方法略}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
主站蜘蛛池模板: 垃圾处理设备_餐厨垃圾处理设备_厨余垃圾处理设备_果蔬垃圾处理设备-深圳市三盛环保科技有限公司 | 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 昆山PCB加工_SMT贴片_PCB抄板_线路板焊接加工-昆山腾宸电子科技有限公司 | 高铝砖-高铝耐火球-高铝耐火砖生产厂家-价格【荣盛耐材】 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 餐饮小吃技术培训-火锅串串香培训「何小胖培训」_成都点石成金[官网] | 苏州注册公司_苏州代理记账_苏州工商注册_苏州代办公司-恒佳财税 | 打孔器,打孔钳厂家【温州新星德牌五金工具】| POS机办理_个人POS机免费领取 - 银联POS机申请首页 | 深圳市索富通实业有限公司-可燃气体报警器 | 可燃气体探测器 | 气体检测仪 | 全自动变压器变比组别测试仪-手持式直流电阻测试仪-上海来扬电气 | 爱佩恒温恒湿测试箱|高低温实验箱|高低温冲击试验箱|冷热冲击试验箱-您身边的模拟环境试验设备技术专家-合作热线:400-6727-800-广东爱佩试验设备有限公司 | 天津货架厂_穿梭车货架_重型仓储货架_阁楼货架定制-天津钢力仓储货架生产厂家_天津钢力智能仓储装备 | 土壤墒情监测站_土壤墒情监测仪_土壤墒情监测系统_管式土壤墒情站-山东风途物联网 | 齿辊分级破碎机,高低压压球机,立式双动力磨粉机-郑州长城冶金设备有限公司 | 退火炉,燃气退火炉,燃气热处理炉生产厂家-丹阳市丰泰工业炉有限公司 | 天津次氯酸钠酸钙溶液-天津氢氧化钠厂家-天津市辅仁化工有限公司 | 武汉画册印刷厂家-企业画册印刷-画册设计印刷制作-宣传画册印刷公司 - 武汉泽雅印刷厂 | 安全阀_弹簧式安全阀_美标安全阀_工业冷冻安全阀厂家-中国·阿司米阀门有限公司 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 喷砂机厂家_自动喷砂机生产_新瑞自动化喷砂除锈设备 | 电梯乘运质量测试仪_电梯安全评估测试仪-武汉懿之刻 | 焊接减速机箱体,减速机箱体加工-淄博博山泽坤机械厂 | 江苏齐宝进出口贸易有限公司 | 新型游乐设备,360大摆锤游乐设备「诚信厂家」-山东方鑫游乐设备 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 制丸机,小型中药制丸机,全自动制丸机价格-甘肃恒跃制药设备有限公司 | 东莞精密模具加工,精密连接器模具零件,自動機零件,冶工具加工-益久精密 | 创绿家招商加盟网-除甲醛加盟-甲醛治理加盟-室内除甲醛加盟-创绿家招商官网 | 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 反渗透阻垢剂-缓蚀阻垢剂厂家-循环水处理药剂-山东鲁东环保科技有限公司 | 叉车电池-叉车电瓶-叉车蓄电池-铅酸蓄电池-电动叉车蓄电池生产厂家 | 电销卡_稳定企业大语音卡-归属地可选-世纪通信 | 电动液压篮球架_圆管地埋式篮球架_移动平箱篮球架-强森体育 | 网带通过式抛丸机,,网带式打砂机,吊钩式,抛丸机,中山抛丸机生产厂家,江门抛丸机,佛山吊钩式,东莞抛丸机,中山市泰达自动化设备有限公司 | 岩棉板|岩棉复合板|聚氨酯夹芯板|岩棉夹芯板|彩钢夹芯板-江苏恒海钢结构 | 精准猎取科技资讯,高效阅读科技新闻_科技猎 | 硫酸亚铁-聚合硫酸铁-除氟除磷剂-复合碳源-污水处理药剂厂家—长隆科技 | 武汉天安盾电子设备有限公司 - 安盾安检,武汉安检门,武汉安检机,武汉金属探测器,武汉测温安检门,武汉X光行李安检机,武汉防爆罐,武汉车底安全检查,武汉液体探测仪,武汉安检防爆设备 | 电脑知识|软件|系统|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网 | 花纹铝板,合金铝卷板,阴极铝板-济南恒诚铝业有限公司 |