SpringSecurity实现动态加载权限信息的方法

网友投稿 290 2022-09-05


SpringSecurity实现动态加载权限信息的方法

①数据库中资源与角色对应关系,以及角色和用户对应关系如下图所示:

②实现FilterInvocationSecurityMetadataSource类

(1)List

(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

//- 遍历数据库的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();

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'
下一篇:SyntaxError: Missing parentheses in call to 'print'. Did you mean print
相关文章

 发表评论

暂时没有评论,来抢沙发吧~