【问题标题】:Spring Security 2.0.x - Filter based on role type + Session based bean stateSpring Security 2.0.x - 基于角色类型的过滤器 + 基于会话的 bean 状态
【发布时间】:2010-10-19 18:47:30
【问题描述】:

我们有一个应用程序,具有代理权限的用户需要能够查看应用程序中的链接。

例如,我们可能有:

<s:intercept-url pattern="/resourceManager.htm" access=" ROLE_ADMIN_GROUP, ROLE_PROXY"/>

如果用户具有代理角色,但没有管理员角色,我需要向他们展示一个页面,告诉他们需要处于代理模式才能看到此页面。此外,我需要检查他们代理的用户的权限,以验证他们具有正确的角色。

我们有多个页面,所以我想在过滤器中执行此逻辑,以便我们可以全面应用该逻辑。

在我继续研究的同时,我正在用伪代码对此进行模拟。

class Filter 
{

protected void doFilterHttp()
{

  //proxy summary is session based object
  if(proxySummary.isProxyMode())
  {
     user = proxySummary.getProxiedUser()
     //here load user's authorities 
     //will have to look at ldap authorities populator, but I should be able to work this part out
  }
  if(user.getGrantedAuthorities.contains("Role_Proxy"))
  {

    //Is there any way to tell possible valid roles for a url?
    if(url.getPossibleRoles() intersect user.getGrantedAuthorities().size == 1 &&    
      intersection.contains(Role_Proxy))
       { redirectToProxyPage(); }
  }

}

为我尝试访问的网址获取任何元数据的最佳方式是什么?

如果无法获取有关 url 的所有允许角色的信息,那么我想我必须在页面上进行。

升级到 Spring Security 3 会给我更多的灵活性吗?

【问题讨论】:

  • 我正在使用自定义 runAsManager(技术上是 runAsProxy)将上述内容实现为安全过滤器拦截器。它似乎按预期运行,但是我需要确保我没有做任何会导致性能问题的事情。如果可行,将发布代码。

标签: spring-security


【解决方案1】:

我最终创建了一个 runAsManager 实现,该实现在代理模式下作为代理用户运行。否则,如果用户只有链接的代理角色,他们会被重定向。 runAsManager 仅在代理模式下修改身份验证对象。

我已经包含了每个类的sn-ps,以免帖子太长。

RunAsProxy 代码段

    public Authentication buildRunAs(Authentication authentication, Object object,
        ConfigAttributeDefinition config) {

            //probably need to do something to cache the proxied user's roles
    if(proxySummary.isProxyMode())
    {
    SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(contextSource);
    String dn = proxySummary.getLoggedInUser();

    String [] tmp = { "uid", "cn" };
    DirContextOperations user = template.retrieveEntry(dn, tmp);


    GrantedAuthority[] proxiedAuthorities = authoritiesPopulator.getGrantedAuthorities(user, user.getStringAttribute("cn").toString());

    return new RunAsUserToken(this.key, authentication.getPrincipal(), authentication.getCredentials(),
            proxiedAuthorities, authentication.getClass());

    }

    return null;



}

拦截器代码 -> 扩展 AbstractSecurityInterceptor 实现过滤器,有序

  public void invoke(FilterInvocation fi) throws IOException, ServletException {

//same code as from proxy security interceptor here ...

                           //config attributes are the roles assigned to a link
                   ConfigAttributeDefinition cad = ((DefaultFilterInvocationDefinitionSource)objectDefinitionSource).lookupAttributes(fi.getRequestUrl());
                   if(cad != null)
                   {
                       HashSet<String> configAttributes = new HashSet<String>();
                       for(Object ca: cad.getConfigAttributes())
                       {
                           configAttributes.add(((ConfigAttribute)ca).getAttribute());
                       }

                       SecurityContext sc  = SecurityContextHolder.getContext();
                       HashSet<String> authorities = new HashSet<String>();
                       for(GrantedAuthority ga: sc.getAuthentication().getAuthorities())
                       {
                           authorities.add(ga.getAuthority());
                       }

                       //intersection and remaining available roles to determine
                                   //if they just have the proxy role
                       authorities.retainAll(configAttributes);
                       if(authorities.size() == 1 && authorities.contains("ROLE_PROXY"))
                       {

                                     //redirect to page telling them to proxy
                                                            ((HttpServletResponse)fi.getResponse()).sendRedirect("jsp/doProxy.jsp");
                       }


                    //System.out.println(cad);
                    fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
              //other boilderplate code                     
        }

弹簧设置

<bean id="proxySecurityInterceptor" class="org.springframework.security.intercept.web.ProxySecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="accessDecisionManager" ref="_accessManager"/>
  <property name="proxySummary" ref="proxySummary" />
  <property name="runAsManager" ref="runAsProxy" />
  <property name="objectDefinitionSource">
  <s:filter-invocation-definition-source>
    <s:intercept-url pattern="/groupManager.htm*" access="ROLE_GLOBAL_ADMIN, ROLE_ADMIN_GROUP, ROLE_PROXY"/>
  </s:filter-invocation-definition-source>
  </property>
  <s:custom-filter after="FILTER_SECURITY_INTERCEPTOR" />
</bean>

【讨论】:

    猜你喜欢
    • 2013-06-20
    • 1970-01-01
    • 2017-10-19
    • 2020-12-18
    • 2016-10-14
    • 2016-07-01
    • 2019-08-08
    • 2018-11-28
    • 1970-01-01
    相关资源
    最近更新 更多