Grails Spring Security获取当前页面的角色

时间:2014-02-27 15:49:20

标签: grails spring-security

我想知道是否有人知道一种优雅的方式来获得Spring安全插件中可以访问当前页面的所有角色。

我正在使用spring security,它被配置为使用RequestMap域对象。

我的应用程序中的权限非常复杂,所以我想在每个页面底部制作一个标记,显示需要使用该页面的角色。

我正在查询请求图,但我想确保我匹配url的方式与插件的方式相同。

理想情况下,我根本不需要运行查询。

Grails版本2.2.1 Spring Security Plugin版本1.2.7.3

提前致谢

1 个答案:

答案 0 :(得分:2)

我通过将以下两个类添加到我的src / java中来实现此目的。

第1类

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

FilterInvocationSecurityMetadataSource oldBean;

@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
    FilterInvocation filterInvocation = (FilterInvocation) o;
    HttpServletRequest request = filterInvocation.getHttpRequest();
    request.setAttribute("PAGEROLES", oldBean.getAttributes(filterInvocation));

    return oldBean.getAttributes(o);
}

@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
    return oldBean.getAllConfigAttributes();
}

@Override
public boolean supports(Class<?> aClass) {
    return FilterInvocation.class.isAssignableFrom(aClass);
}

public Object getOldBean() { return oldBean; }
public void setOldBean(FilterInvocationSecurityMetadataSource oldBean) { this.oldBean = oldBean; }
}

第2类

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

public class FilterSecurityMDSExtractor implements BeanPostProcessor, BeanFactoryAware {
    private ConfigurableListableBeanFactory bf;
    private FilterInvocationSecurityMetadataSource metadataSource = new MyFilterInvocationSecurityMetadataSource();

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof FilterInvocationSecurityMetadataSource) {
            ((MyFilterInvocationSecurityMetadataSource) metadataSource).setOldBean((FilterInvocationSecurityMetadataSource) bean);
            return metadataSource;
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.bf = (ConfigurableListableBeanFactory)beanFactory;
    }
}

然后我将以下内容添加到resources.groovy

beans = {
      filterSecurityMDSExtractor(FilterSecurityMDSExtractor)
}

基本上我将用户角色填入请求

request.setAttribute("PAGEROLES", oldBean.getAttributes(filterInvocation));

然后我所要做的就是调用以下

request.getAttribute("PAGEROLES");

让角色退出。我通过窃取Stackoverflow上的其他好帖子拼凑了我的解决方案。其他人可能有更好的解决方案,但到目前为止这对我有用。