Spring security custom FilterInvocationSecurityMetadataSource implementation 403 forbidden issue

浪尽此生 提交于 2019-12-02 03:11:37

I managed to get into the security flow by debugging and it seems that by creating ConfigAttributes of this SecurityConfig class is the 'culprit'

return SecurityConfig.createList(stockArr);
public static List<ConfigAttribute> createList(String... attributeNames) {
    Assert.notNull(attributeNames, "You must supply an array of attribute names");
    List<ConfigAttribute> attributes = new ArrayList(attributeNames.length);
    String[] var2 = attributeNames;
    int var3 = attributeNames.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        String attribute = var2[var4];
        attributes.add(new SecurityConfig(attribute.trim()));
    }

    return attributes;
}

Above is the actual implementation of the method where you can see

attributes.add(new SecurityConfig(attribute.trim()));

And this always creates an instance of SecurityConfig type.

And below you can actually see where and how the decision is being made.

private WebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
    Iterator var2 = attributes.iterator();

    ConfigAttribute attribute;
    do {
        if (!var2.hasNext()) {
            return null;
        }

        attribute = (ConfigAttribute)var2.next();
    } while(!(attribute instanceof WebExpressionConfigAttribute));

    return (WebExpressionConfigAttribute)attribute;
}

So in order for it to actually return a configattribute for checking it must be of type WebExpressionConfigAttribute which is never going to be the case because of this

attributes.add(new SecurityConfig(attribute.trim()));

So the way I fixed it is to create my own accessDecisionManager the following way

public class MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
        throws AccessDeniedException, InsufficientAuthenticationException {
    if(configAttributes == null){
        return  ;
    }
    Iterator<ConfigAttribute> ite = configAttributes.iterator();
    while(ite.hasNext()){

        ConfigAttribute ca = ite.next();

        String needRole = ((SecurityConfig)ca).getAttribute();

        for(GrantedAuthority grantedAuthority : authentication.getAuthorities()){
            if(needRole.trim().equals(grantedAuthority.getAuthority().trim())){
                return;
            }
        }
    }
    throw new AccessDeniedException("Access is denied");
}

And registering as above now setting the accessdecisionManager with my custom one

.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
        public <O extends FilterSecurityInterceptor> O postProcess(
                O fsi) {
            FilterInvocationSecurityMetadataSource newSource = new DbFilterInvocationSecurityMetadataSource();
            fsi.setSecurityMetadataSource(newSource);
            fsi.setAccessDecisionManager(new MyAccessDecisionManager());
            return fsi;
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!