返回介绍

5.4 权限管理设计

发布于 2025-04-26 13:26:33 字数 6302 浏览 0 评论 0 收藏 0

用户通过身份认证,成功登录系统后,就要开始检查用户访问资源的权限,如果用户没有权限访问,将会阻止用户访问受保护的资源,并给出错误提示信息。

5.4.1 权限管理配置

在安全配置类中,定义了几个类,实现自定义的权限检查判断及其管理的功能,如代码清单 5-19 所示,各个类的意义如下:

- CustomFilterSecurityInterceptor:权限管理过滤器。

- CustomAccessDecisionManager:权限管理决断器。

- CustomSecurityMetadataSource:权限配置资源管理器。

其中,过滤器在系统启动时开始工作,并同时导入资源管理器和权限决断器,对用户访问的资源进行管理。权限决断器对用户访问的资源与用户拥有的角色权限进行对比,以此来判断一个用户是否对一个资源具有访问权限。

代码清单 5-19 安全配置类中的权限管理设置

@Bean
    public CustomFilterSecurityInterceptor customFilter() throws Exception{
        CustomFilterSecurityInterceptor customFilter = new CustomFilterSecurityInterceptor();
        customFilter.setSecurityMetadataSource(securityMetadataSource());
        customFilter.setAccessDecisionManager(accessDecisionManager());
        customFilter.setAuthenticationManager(authenticationManager);
        return customFilter;
    }
    @Bean
    public CustomAccessDecisionManager accessDecisionManager() {
        return new CustomAccessDecisionManager();
    }
    @Bean
    public CustomSecurityMetadataSource securityMetadataSource() {
        return new CustomSecurityMetadataSource(settings.getUrlroles());
    }

5.4.2 权限管理过滤器

权限管理过滤器继承于 Spring Security 的 AbstractSecurityInterceptor,实时监控用户的行为,防止用户访问未被授权的资源,如代码清单 5-20 所示。

代码清单 5-20 权限管理过滤器

public class CustomFilterSecurityInterceptor extends AbstractSecurity
Interceptor implements Filter {
    private static final Logger logger = Logger.getLogger(CustomFilterSecurityInterceptor.class);
    private FilterInvocationSecurityMetadataSource securityMetadataSource;
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain
chain) throws IOException, ServletException {
        FilterInvocation fi = new FilterInvocation(request, response, chain);
        logger.debug("===="+fi.getRequestUrl());
        invoke(fi);
    }
    public void invoke(FilterInvocation fi) throws IOException, ServletException {
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            super.afterInvocation(token, null);
        }
}
}……





5.4.3 权限配置资源管理器

权限配置资源管理器实现了 Spring Security 的 FilterInvocationSecurityMetadataSource,它在启动时导入代码清单 5-4 的权限配置列表。如代码清单 5-21 所示,权限配置资源管理器为权限决断器实时提供支持,判断用户访问的资源是否在受保护的范围之内。

代码清单 5-21 权限配置资源管理器

public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource{
    private static final Logger logger = Logger.getLogger(CustomSecurityMetadataSource .class);
    private Map<String, Collection<ConfigAttribute>> resourceMap = null;
    private PathMatcher pathMatcher = new AntPathMatcher();
    private String urlroles;
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }
    public CustomSecurityMetadataSource  (String urlroles) {
        super();
        this.urlroles = urlroles;
        resourceMap = loadResourceMatchAuthority();
    }
    private Map<String, Collection<ConfigAttribute>> loadResourceMatchAuthority() {
        Map<String, Collection<ConfigAttribute>> map = new HashMap<String, Collection<ConfigAttribute>>();
        if(urlroles != null && !urlroles.isEmpty()){
            String[] resouces = urlroles.split(";");
            for(String resource : resouces){
                String[] urls = resource.split("=");
                String[] roles = urls[1].split(",");
                Collection<ConfigAttribute> list = new ArrayList<ConfigAttri
bute>();
                for(String role : roles){
                    ConfigAttribute config = new SecurityConfig(role.trim());
                    list.add(config);
                }
                // key:




url, value:




roles
                map.put(urls[0].trim(), list);
            }
        }else{
            logger.error("'securityconfig.urlroles' must be set");
        }
        logger.info("Loaded UrlRoles Resources.");
        return map;
    }
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        String url = ((FilterInvocation) object).getRequestUrl();
        logger.debug("request url is  " + url);
        if(resourceMap == null)
            resourceMap = loadResourceMatchAuthority();
        Iterator<String> ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
            String resURL = ite.next();
            if (pathMatcher.match(resURL,url)) {
                return resourceMap.get(resURL);
            }
        }
        return resourceMap.get(url);
    }
    ......
}

5.4.4 权限管理决断器

权限管理的关键部分就是决断器,它实现了 Spring Security 的 AccessDecision-Manager,重载了 decide 函数,使用了自定义的决断管理,如代码清单 5-22 所示。在用户访问受保护的资源时,决断器判断用户拥有的角色中是否对该资源具有访问权限,如果没有权限将被拒绝访问,并返回错误提示。

代码清单 5-22 权限管理决断器

public class CustomAccessDecisionManager implements AccessDecisionManager {
    private static final Logger logger = Logger.getLogger(CustomAccessDecisionManager.class);
    @Override
    public void decide(Authentication authentication, Object object, Collec
tion<ConfigAttribute> configAttributes)throws AccessDeniedException, InsufficientAuthenticationException {
        if (configAttributes == null) {
            return;
        }
        // config urlroles
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while (iterator.hasNext()) {
            ConfigAttribute configAttribute = iterator.next();
            // need role
            String needRole = configAttribute.getAttribute();
            // user roles
            for (GrantedAuthority ga : authentication.getAuthorities()) {
                if (needRole.equals(ga.getAuthority())) {
                    return;
                }
            }
            logger.info("need role is " + needRole);
        }
        throw new AccessDeniedException("Cannot Access!");
    }
    ……





}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。