views:

35

answers:

1

We have an application where users with proxy rights need to be able to see links in an application.

For example, we might have:

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

If the user has the role of proxy, but not the admin role, I need to present them with a page telling them that they need to be in proxy mode to see this page. Additionally, I need to check the permissions of the user they proxy to, to verify they have the correct role.

We have multiple pages, so I'd like to like to do this logic in a filter, so we can apply the logic across the board.

I'm mocking this up in pseudo code while I continue to research.

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(); }
  }

}

What's the best way to get any metadata for the url I'm attempting to access?

If there is no way to get information on all allowable roles for a url, then I imagine I would have to do it at the page.

Would upgrading to Spring Security 3 give me any more flexibility?

A: 

I ended up creating a runAsManager implementation that ran as the proxy user if in proxy mode. Otherwise, if the user only had a proxy role for the link, they were redirected. The runAsManager only modified the authentication object when in proxy mode.

I've included snippets of each class, so as not to make the post too long.

RunAsProxy Snippet

    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;



}

Interceptor Code -> extends AbstractSecurityInterceptor implements Filter, Ordered

  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                     
        }

Spring Setup

<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>
Scott

related questions