一聚教程网:一个值得你收藏的教程网站
PHP教程 Css教程 操作系统 数据库 安卓下载
英魂之刃最新版
末日血战
崩坏3手机版
天使之战最新版
正版原始传奇
创造与魔法正版手游
时空猎人3正式版手游
古剑世界手机版
卧龙吟安卓版
少年三国志正版
《暗黑破坏神:不朽》新职业Coser今日亮相2024ChinaJoy
《物华弥新》闪耀2024CJ 8月新版本福利享不停
长安城“导游”招募开启,和兄弟组团共赴大话嘉年华
《蛋仔派对》首届蛋仔电影节隆重开幕,播映主题全公开
暑期不无聊,《蛋仔派对》和《疯狂动物城》联动重磅上线
齐力挖金 《一梦江湖》七夕节双人黄金矿工玩法刺激开启
《梦幻西游三维版》暑期活动进行中,全新锦衣潮翻三界
KK联动虎牙澄海主播邀请赛圆满落幕,高玩云集巅峰会战
《阴阳师》全新结界皮肤华夜枫舞 即将上线
CS2沙二A小假打烟雾弹攻略
时间:2022-06-29 01:58:56 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下SpringSecurity实现动态加载权限信息代码方法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
①数据库中资源与角色对应关系,以及角色和用户对应关系如下图所示:
②实现FilterInvocationSecurityMetadataSource类
(1)List
(2)重写的support方法都返回true
@Configuration public class MyFilterInvocation implements FilterInvocationSecurityMetadataSource { @Autowired private MenuService menuService; AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override public Collection getAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); List menus = menuService.getMenusWithRoles(); //- 遍历数据库的url,看请求路径是否与其匹配 for (Menu menu : menus) { //- 如果请求路径和数据库的路径匹配 if (antPathMatcher.match(menu.getUrl(),requestUrl)){ //- 访问该路径需要的角色 List roles = menu.getRoles(); String[] strs = new String[roles.size()]; for (int i = 0; i < roles.size(); i++) { strs[i] = roles.get(i).getName(); } return SecurityConfig.createList(strs); } } //- 如果请求路径和数据库的所有路径都不匹配,说明这个资源是登录后即可访问的 //- 用户登录即可访问,相当于在SecurityConfig中配置了.anyRequest().authenticated() return SecurityConfig.createList("ROLE_LOGIN"); } @Override public Collection getAllConfigAttributes() { return null; } @Override public boolean supports(Class> clazz) { return true; } }
③实现AccessDecisionManager类
重写的support方法都返回true
@Configuration public class MyDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { for (ConfigAttribute configAttribute : configAttributes) { String needRole = configAttribute.getAttribute(); if ("ROLE_LOGIN".equals(needRole)) { //- 用户登录即可访问,相当于在SecurityConfig中配置了.anyRequest().authenticated() if (authentication instanceof AnonymousAuthenticationToken) { throw new AccessDeniedException("尚未登录,请先登录"); } else { return; } } Collection extends GrantedAuthority> authorities = authentication.getAuthorities(); //这里我写的是只要访问该资源的用户具有`访问该资源所需要角色`的其中一个即可 for (GrantedAuthority authority : authorities) { if (authority.getAuthority().equals(needRole)) { return; } } } throw new AccessDeniedException("权限不足,请联系管理员"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class> clazz) { return true; } }
④到SecurityConfig配置类中完成相应配置
@Autowired private MyDecisionManager myDecisionManager; @Autowired private MyFilterInvocation myFilterInvocation; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .withObjectPostProcessor(new ObjectPostProcessor() { @Override public O postProcess(O object) { object.setAccessDecisionManager(myDecisionManager); object.setSecurityMetadataSource(myFilterInvocation); return object; } }); http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler()); } @Bean MyAccessDeniedHandler myAccessDeniedHandler(){ return new MyAccessDeniedHandler(); }
⑤可选,实现AccessDeniedHandler类
public class MyAccessDenied implements AccessDeniedHandler { @Override public void handle(HttpServletRequest req, HttpServletResponse resp, AccessDeniedException accessDeniedException) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter pw = resp.getWriter(); pw.write(new ObjectMapper().writeValueAsString(RespBean.error("权限不够,请联系管理员"))); pw.flush(); pw.close(); } }