Spring安全全局预授权规则

时间:2016-11-07 19:12:53

标签: spring spring-security spring-security-oauth2

我正在研究网关后面的服务方法,以便轻松沟通。

该计划使用oauth令牌中的范围,该令牌将由在同一系统上运行的服务使用。

例如。如果oauth令牌具有范围'acct'和'user',则可以使用bellow api方法。在不更改注释的情况下,如果ouath令牌的范围为“admin”并且缺少范围“acct”和“user”,我希望它也可用。

@PreAuthorize("#oauth2.hasScope('acct') and #oauth2.hasScope('user')")
@RequestMapping(value = "/scopedtest", produces = "application/json")
public Map<String, String> indexWithScope() {
    return getHashMapResult();
}

我希望这个'admin'范围被全局接受,以便服务开发人员不需要在他们制作的每个api控制器上包含管理范围,但仍允许内部服务访问其他内部服务的apis。

这将作为代码拦截调用预授权并将响应更改为调用者具有'admin'范围的授权。如果oauth令牌具有预授权注释所需的范围,则调用将正常运行。

2 个答案:

答案 0 :(得分:2)

通过在现有的决策选民名单中添加一名选民来解决这个问题。

第一步是创建一个自定义选民类

public class CustomVoter implements AccessDecisionVoter {

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public int vote(Authentication authentication, Object object, Collection collection) {
        //Place your decision code here
        if( check_is_true() ) {
            //grant access
            return ACCESS_GRANTED;
        } else if ( check_is_false() ) {
            //deny access
            return ACCESS_DENIED;
        } else {
            //do not make a choice
            return ACCESS_ABSTAIN;
        }
    }

    @Override
    public boolean supports(Class clazz) {
        return true;
    }
}

我们现在需要将这个选民添加到将作出访问决定的选民名单中。

@Configuration
public class DecisionVotersConfiguration {

    @Autowired
    MethodInterceptor methodSecurityInterceptor;

    @PostConstruct
    @DependsOn("methodSecurityInterceptor")
    public void modifyAccessDecisionManager() {
        ((AffirmativeBased)((MethodSecurityInterceptor)methodSecurityInterceptor).getAccessDecisionManager()).getDecisionVoters().add(0, new CustomVoter());
    }
}

这会将您的自定义决策选民添加到决策选民列表中。通过将其放在索引0处,将首先检查它。这将允许选民在以后的检查拒绝访问之前授予访问权限。此配置类中的方法将取决于正在创建的methodSecurityInterceptor,该方法将具有决策选民的初始列表。

答案 1 :(得分:0)

使用WebSecurity

您当前正在对控制器操作使用预授权规则。方法安全的强大功能最初是将其用于与路径直接相关的方法而不是,因为这些方法可以设置HttpSecurity请求匹配器,通常使用WebSecurityConfigurerAdapter。< / p>

然而 - 这并不能真正帮助你,因为Spring有一条通向权限的途径,而不是路由方法的许可。这意味着,如果您有一个全局角色,则无论具体配置如何都可以访问所有内容,而不是必须将其配置为所有安全定义,如果您要避免更改默认配置。

我认为解决您需求的唯一方法是挂钩弹簧安全过滤流程并为管理范围定义一个例外规则。您可以阅读here,了解如何实现自定义过滤器,在提取oauth2身份验证后查找管理范围(或不同的全局规则)

树角色

这是我用于我的项目的一些逻辑解决方案,它赋予角色一些“父”角色,这意味着角色在树中的当前节点。所以root隐式授予您配置的所有角色/范围。为简单起见,我在写入时应用这些树逻辑,比如给[ROOT_ROLE]结果添加(树遍历)下的所有角色,或者撤销深度优先搜索从节点向上发现的所有角色。这里的动机是,访问控制策略通常反映用户的层次结构,并且使用树可以更自由地设计这些个人层次结构。此模式以可扩展的方式间接解决您的问题