关于权限控制,一开始感觉比较难,后来先是接触了Spring Security 学起来也比较吃力,再是学习了Shiro,感觉简单很多。

总体来说这些框架,主要做了两个事情

Authentication身份认证/登录,验证用户是不是拥有相应的身份;

Authorization授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

还做了一些事情,我也没有深入,主要就这么。

从以下配置文件可以看出。

<beans:bean id="myFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">

        <beans:property name="authenticationManager" ref="autheticationManager"></beans:property>
        <beans:property name="accessDecisionManager" >
            <beans:bean class="org.springframework.security.access.vote.AffirmativeBased">
                <beans:property name="decisionVoters">
                    <beans:list>
                        <beans:bean class="org.springframework.security.access.vote.RoleVoter" />
                        <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
                    </beans:list>
                </beans:property>
            </beans:bean>
        </beans:property>
        <!-- resourceService在applicationContext*.xml中或注解定义 -->
        <beans:property name="securityMetadataSource" ref="securityMetadataSource" />
    </beans:bean>

这里有一个authenticationManager是做身份认证的,有一个accessDecisionManager是做授权管理的。还有一个是securityMetadataSource这里主要做的从数据库取出资源与角色的关系,为第二个授权做准备,授权又是根据用户的身份找出他的角色,根据角色判断是否有访问资源的权限。

先介绍这个 securityMetadataSource这里需要实现FilterInvocationSecurityMetadataSource接口,大致如下:

/**

     * resourceMa
     * resourceMap 存储的资源为<Url,Collection<ConfigAttribute>>,其中Collection<ConfigAttribute>为资源对应的角色集合,其构造方式为new SecurityConfig("ROLE_" + role.getRoleId().toString())
     * resourceMap 里面存储的内容为<1个URL,对应得角色的集合>
     * 加载所有的资源与角色的关系
     */
    public void init() throws Exception {
        resourceMap = new HashMap<String,Collection<ConfigAttribute>>();
        List<Resource> resources = resourceDao.findAll();
        
        for(Resource item:resources) {
        String url = item.getUrlpath();
            if(url != null) {
                 List<Role> roles = roleDao.getRolesByResourceId(item.getResourceid());
                if(roles !=null && roles.size()>0) {
                    if(resourceMap.containsKey(item.getUrlpath())) {
                        Collection<ConfigAttribute> old = resourceMap.get(item.getUrlpath());
                        old.addAll(listToCollection(roles));
                    } else {
                        resourceMap.put(url, listToCollection(roles));
                    }
                }
            }
        }
    }
    
    /**
     * 将角色转化为ConfigAttribute
     * @param roles
     * @return
     */
    private Collection<ConfigAttribute> listToCollection(Collection<Role> roles) {
        Collection<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
        for(Role role :roles) {
            ConfigAttribute configAttribute = new SecurityConfig("ROLE_"+role.getRoleid().toString());
            //list.add(new SecurityConfig("ROLE_" + role.getRoleid().toString()));
            list.add(configAttribute);
        }
        return list;
        
    }     /**
     * 将资源与权限的对应关系Map转化为Security需要的Collection
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
        for(Map.Entry<String, Collection<ConfigAttribute>>  entry:resourceMap.entrySet()) {
            allAttributes.addAll(entry.getValue());
        }
        return allAttributes;
    }  //返回所请求资源所需要的权限   public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); System.out.println("requestUrl is " + requestUrl); if(resourceMap == null) { try { init(); } catch (Exception e) { e.printStackTrace(); } } return resourceMap.get(requestUrl); } 

上面前几个方法是在程序启动的时候执行,最后一个方法是在你要访问某个资源的时候自动调用的最终返回的是 Collection<ConfigAttribute>  权限集合。

accessDecisionManager授权管理,根据上面返回的权限集合,和用户登录存储的用户权限进行对比判断用户是否有访问权限,自己写授权管理的话需要实现AccessDecisionManager 接口,如下:

public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        if(configAttributes == null) {
            return;
        }
        //所请求的资源拥有的权限(一个资源对多个权限)
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while(iterator.hasNext()) {
            ConfigAttribute configAttribute = iterator.next();
            //访问所请求资源所需要的权限
            String needPermission = configAttribute.getAttribute();
            System.out.println("needPermission is " + needPermission);
            //用户所拥有的权限authentication
            for(GrantedAuthority ga : authentication.getAuthorities()) {
                if(needPermission.equals(ga.getAuthority())) {
                    return;
                }
            }
        }
        //没有权限让我们去捕捉
        throw new AccessDeniedException(" 没有权限访问!");

}

authenticationManager身份认证,主要包含登陆这些,框架一般会给我们提供form表单提交的处理接口,我们需要实现接口和配置一些相关配置。

<http auto-config="true" access-denied-page="/accessDenied.jsp" use-expressions="true">

        <form-login login-page="/index.jsp" login-processing-url="/j_spring_security_check"
        always-use-default-target="true" authentication-failure-url="/index.jsp?login_error=true"
        default-target-url="/frame.jsp"
        />
                
        <logout logout-success-url="/index.jsp"/>
        <intercept-url pattern="/style/**" filters="none" />
        <intercept-url pattern="/js/**" filters="none" />
         <intercept-url pattern="/index.jsp" filters="none" />
        <intercept-url pattern="/login.action" filters="none"/>
        <intercept-url pattern="/frame.jsp" access="isAuthenticated()"/>
        <anonymous />
        <session-management invalid-session-url="/accessDenied.jsp">
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>
        <!-- 将自己的过滤器加入到过滤器链中, 放在FILTER_SECURITY_INTERCEPTOR之前-->
        <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
    </http>
    
    <authentication-manager alias="autheticationManager">
        <!-- 使用自定义UserDetailsService -->
        <authentication-provider user-service-ref="userService"/>

</authentication-manager>

以上是Spring Security的配置,还需要在userService 登录验证里面实现UserDetailsService 接口。Shiro实现方式如下 :

Subject currentUser = SecurityUtils.getSubject();

        System.out.println(EncryptUtils.encryptMD5(user.getPassword()));
        UsernamePasswordToken token = new UsernamePasswordToken(
                user.getUsercode(), EncryptUtils.encryptMD5(user.getPassword()));
        token.setRememberMe(true);
        try {
            currentUser.login(token);
        } catch (AuthenticationException e) {
            modelView.addObject("message", "login errors");
            modelView.setViewName("/login");
            e.printStackTrace();
            

}

accessDecisionManager

权限控制框架Spring Security 和Shiro 的总结的更多相关文章

  1. 了解权限控制框架shiro 之实际应用.

    Apache Shiro 1.权限控制分为 a.粗粒度 URL 级别权限控制     b.细粒度方法级别权限控制 2.使用shiro进行权限控制主要有四种主要方式 : a. 在程序中 通过 Subje ...

  2. 项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示

    1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 ...

  3. Spring Security和Shiro的比较和使用

    https://blog.csdn.net/it_java_shuai/article/details/78054951 Spring Security和Shiro的比较和使用 2017年09月21日 ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 (Spring Security 版本 )

    技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro 也足够好用并且简单,但对于 Spring 官方主推的安全框架 Spring Security,用户群也是甚大的,所以我们这 ...

  5. Flex-Security权限控制框架

    转自:http://code.google.com/p/flex-security/ flex UI组件权限控制框架 一.快速开始 1) 下载并添加flex_security.swf在你的flex l ...

  6. WPF权限控制框架——【4】抛砖引玉

    写第一篇"权限控制框架"系列博客是在2021-01-29,在这不到一个月的时间里,收集自己零碎的时间,竟然写出了一个"麻雀虽小,五脏俱全"的权限控制框架:对于一 ...

  7. 权限控制框架Shiro简单介绍及配置实例

    Shiro是什么 http://shiro.apache.org/ Apache Shiro是一个非常易用的Java安全框架,它能提供验证.授权.加密和Session控制.Shiro非常轻量级,而且A ...

  8. shiro权限控制(一):shiro介绍以及整合SSM框架

    shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证.授权.加密和会话管理等功能 . shiro能做什么? 认证:验证用户的身份 授权:对用户执行访问控制:判断用户是 ...

  9. 第十九章 动态URL权限控制——《跟我学Shiro》

    目录贴:跟我学Shiro目录贴 用过Spring Security的朋友应该比较熟悉对URL进行全局的权限控制,即访问URL时进行权限匹配:如果没有权限直接跳到相应的错误页面.Shiro也支持类似的机 ...

随机推荐

  1. MATLAB中return和break

    return: RETURN Return to invoking function. RETURN causes a return to the invoking function or to th ...

  2. hdu 4735Little Wish~ lyrical step~ 重复覆盖

    题目链接 给出一棵树, 树上点的值为0或1, 可以交换树上两个点的权值, 给出一个距离m, 所有的0距离最近的1的距离不能超过m, 求最少的交换次数. 首先对于每一个点u,所有离u的距离不超过m的点v ...

  3. thoughtbot/capybara-webkit

    thoughtbot/capybara-webkit A capybara driver that uses WebKit via QtWebKit. Qt Dependency and Instal ...

  4. angular学习(一):动态模板总结

    近期在项目中用到了angular,之前从未用到过此js lib库,因为项目也比較着急,学习的寥寥草草.到眼下为止也仅仅是学会皮毛而已,现将自己学习的知识总结例如以下: 备注1: 版本:1.2.2 备注 ...

  5. C++ signal的使用

    1.头文件 #include  <signal.h> 2.功能 设置某一信号的对应动作 3.函数原型 typdef  void  (*sighandler_t )(int); sighan ...

  6. 关于ue上传图片到七牛云设置key

    多图上传设置key: dialogs文件下面,image文件下面的image.html,链接webuploader.js,不链接webuploader.min.js webuploader.js里面 ...

  7. HTTP请求和数据安全

    /*------------------------------------- 01 HTTP请求 ---------------------------------------*/ 重点:1.超文本 ...

  8. Linux新手笔记 sudo

    centos 6.4 32bit 你是也像我一样,厌烦了在root用户和个人用户之间来回切换.或者干脆直接用root用户.可以这样设置,然后在命令前加sudo 即可使用自己到密码,临时用root身份执 ...

  9. 零行代码为App添加异常加载占位图

    前文提要 近期准备重构项目,需要重写一些通用模块,正巧需要设置App异常加载占位图的问题,心血来潮设想是否可以零行代码解决此问题,特在此分享实现思路. 思路分享 对于App占位图,通常需要考虑的控件有 ...

  10. PHP新手必须掌握的入门与实战技巧

    作为当今主流的开发语言,PHP集简单.免费.高效等特点于一身.对于想加入PHP大军的新手来说,从何学起.如何学习? 你需要掌握PHP的基础知识.常用功能模块.面向对象.MVC等相关技能.学会了这些技能 ...