SpringSecurity实现动态加载权限信息的方法
短信预约 -IT技能 免费直播动态提醒
①数据库中资源与角色对应关系,以及角色和用户对应关系如下图所示:
②实现FilterInvocationSecurityMetadataSource类
(1)List<Menu> menus = menuService.getMenusWithRoles();这个是你自己的资源对应角色的查询方法。
(2)重写的support方法都返回true
@Configuration
public class MyFilterInvocation implements FilterInvocationSecurityMetadataSource {
@Autowired
private MenuService menuService;
AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
String requestUrl = ((FilterInvocation) object).getRequestUrl();
List<Menu> menus = menuService.getMenusWithRoles();
//- 遍历数据库的url,看请求路径是否与其匹配
for (Menu menu : menus) {
//- 如果请求路径和数据库的路径匹配
if (antPathMatcher.match(menu.getUrl(),requestUrl)){
//- 访问该路径需要的角色
List<Role> 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<ConfigAttribute> 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<ConfigAttribute> 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<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> 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();
}
}
到此这篇关于SpringSecurity实现动态加载权限信息的文章就介绍到这了,更多相关SpringSecurity动态加载权限内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341