acegi security实践教程—访问系统中资源前必须登陆系统

问题:

  处于安全角度,访问本系统时,是需要登陆才可以访问其下的资源。根据上篇博客的调试,我们发现,若其url在数据库中没有没有配置其角色,则是可以直接访问其url的。
  那为了避免这种情况,我们如何改进自己的系统,进一步接近真实的企业开发呢?
概要:
  这节我们将会讲到匿名权限,securitycontext中随时都包含权限,而不是只有登录后才有。
  进一步改进上一篇博客中自定义objectDefinitionSource类,因为若返回null,则直接进入其url。

具体开发:
开发环境:

  MyEclispe10.7.1+tomcat6.0.37+acegi1.0.5+spring2.0+jdk1.6【其中数据库和数据结构保持不变】
项目目录如下:  
  其中readme主要用来记录本次验证目的

配置匿名Filter:

  
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,
anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
    <!--匿名过滤器 -->
    <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
      <!-- 其中key随意提供一个名字即可,但是必须提供,类似用户名 -->
      <property name="key" value="test"></property>
      <!-- userAttribute提供了其密码和相应的角色 -->
      <property name="userAttribute" value="testpwd,ROLE_ANONYMOUS"></property>
    </bean>

配置原因:

  根据以往的经验,我们还是来看其源码,为什么必须提供key以及userAttribute呢?
  doFilter中的:
  SecurityContextHolder.getContext().setAuthentication(createAuthentication(request));
  而createAuthentication代码如下:
      protected Authentication createAuthentication(ServletRequest request) {
        Assert.isInstanceOf(HttpServletRequest.class, request,
            "ServletRequest must be an instance of HttpServletRequest");
        AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, userAttribute.getPassword(),
                userAttribute.getAuthorities());
        auth.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
        return auth;
    }
  而AnonymousAuthenticationToken代码:
      public AnonymousAuthenticationToken(String key, Object principal, GrantedAuthority[] authorities) {
        super(authorities);
        if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (authorities == null)
            || (authorities.length == 0)) {
            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
        }
        this.keyHash = key.hashCode();
        this.principal = principal;
        setAuthenticated(true);
    }
  所以key、principal【密码】、authorities 三个属性必须配置,通过这三个属性来new一个匿名的权限,然后存放到securitycontext中,这样SecurityContextHolder.getContext().getAuthentication()中的权限不是null,而是匿名的权限,其中角色信息ROLE_ANONYMOUS
完善自定义objectDefinitionSource类:
  若是保护资源,则返回数据库中其对应的角色信息;若不是保护资源,我们不返回null,否则直接进入其url,我们返回一个自定义角色信息。
      //若是保护的资源
   if(matched){
    //进一步查询此url的角色权限
    String urlRole="select role from test_resource_role where url=?";
    List<Map> roleList=this.jdbcTemplate.queryForList(urlRole,new Object[]{url});
    return converURLRole(roleList);
   
   }
   
   ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
   configDefinition.addConfigAttribute(new SecurityConfig("IS_AUTHENTICATED_FULLY"));
   return configDefinition;
  这样改进后,我们再看看AbstractSecurityInterceptor中的beforeInvocation方法:

 结果讲解:

 投票失败后,则根据错误分类信息,转向不同的页面。
 另一个注意点:
 若想登陆成功后一直转到默认页面而非访问的目的地时,如何操作?
 比如:访问http://localhost/acegitest8/test.jsp,首先出现login.jsp页面,若登陆成功后,你想跳转到默认的/userinfo.jsp页面。跳转之后,再访问http://localhost/acegitest8/test.jsp。
 无论何种情况,只要登陆后就转到acegi.xml默认的配置页面。如何配置?
 AuthenticationProcessingFilter中alwaysUseDefaultTargetUrl属性默认情况为false,所以只要我们在aceg.xml配置为true即可。
       <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">  
        <!-- 认证管理器,然后委托给Provides -->
        <property name="authenticationManager" ref="authenticationManager"/>  
        <!-- 认证失败后转向的url,包含出错信息的的登陆页面 -->
        <property name="authenticationFailureUrl" value="/login.jsp?login_error=1"/>  
        <!-- 登陆成功后转向的url -->
        <property name="defaultTargetUrl" value="/userinfo.jsp"/>  
        <!-- 登陆的url,这个是默认的acegi自带的 -->
        <property name="filterProcessesUrl" value="/j_acegi_security_check"/>  
        <!-- 永远转到登陆成功后默认的目的地,如上文/userinfo.jsp -->
        <property name="alwaysUseDefaultTargetUrl" value="true"/>
    </bean> 

猜你喜欢

转载自blog.csdn.net/llhhyy1989/article/details/24815361
今日推荐