关于权限控制,一开始感觉比较难,后来先是接触了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. BZOJ 1021: [SHOI2008]Debt 循环的债务( dp )

    dp(i, j, k)表示考虑了前i种钱币(从小到大), Alice的钱数为j, Bob的钱数为k, 最小次数. 脑补一下可以发现, 只有A->B.C, B->A.C, C->A.B ...

  2. StringBuffer&Runtime demo

    public class StringBufferDemo02 {     public static void main(String[] args) {         StringBuffer ...

  3. bzoj 3289: Mato的文件管理 莫队+线段树

    题目链接 给一些询问,每个询问给出区间[L, R] , 求这段区间的逆序数. 先分块排序, 然后对于每次更改, 如果是更改L, 那么应该查询区间内比他小的数的个数, 如果更改R, 查区间内比他大的数的 ...

  4. java 线程学习

    转载:详见处http://lavasoft.blog.51cto.com/62575/27069   Java多线程编程总结   下面是Java线程系列博文的一个编目:   Java线程:概念与原理 ...

  5. hdu 2565 放大的X

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2565 这个题很简单 但是很容易错,写来给自己一个警示把 首先在最后一个x后面没有空格,然后就是那个换行一 ...

  6. Qt qss一些伪装态,以及margin与padding区别

    伪状态    描述 :checked    button部件被选中:disabled    部件被禁用:enabled    部件被启用:focus    部件获得焦点:hover    鼠标位于部件 ...

  7. 微信开放框架-UCToo

    UCToo是一套简单,易用,开源的微信增值应用开发框架,帮助用户快捷的实现微信公众平台的个性化定制功能. http://www.uctoo.com/

  8. [cpp]伯乐在线编程挑战第 0 期 – 呼叫转移系统

    题目: 描述 呼叫转移服务是一个把呼叫号码A转移到号码B的服务.举个例子:当你正在度假时,这样的系统非常有帮助.A君度假去了,那么,A君的工作电话可以通 过呼叫转移至B君.更进一步讲,当B君也正好在度 ...

  9. 类型萃取(type traits)

    1. 类型萃取的作用 类型萃取使用模板技术来萃取类型(包含自定义类型和内置类型)的某些特性,用以判断该类型是否含有某些特性,从而在泛型算法中来对该类型进行特殊的处理用来提高效率或者其他.例如:在STL ...

  10. SpringMVC入门一:helloWorld

    玩了一下SpringMVC, 感觉挺清爽的 好像没有struts那么臃肿( 可能是高级的东西我还不会用 哈 ) 例子中一共有俩方法: 一个Controller直接返回字串的方法, 另一个通过Dao层返 ...