2016-11-07 136 views
2

我正在研究网关后面的服务方法,以便轻松进行通信。Spring安全性全局预授权规则

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

例如。如果oauth令牌具有作用域'acct'和'user',则可以使用bellow api方法。在不更改注释的情况下,我希望它也可用,前提是令牌具有“管理员”范围,并且缺少其中一个或两个范围的“acct”和“user”。

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

我想这个“管理员”范围被全球所接受,使服务开发人员不必包括每个API控制自己给管理员范围,但仍允许内部服务访问的其他内部服务的API 。

这将作为拦截预授权的调用并将响应更改为调用者被授权(如果具有“管理”范围)的代码。如果oauth标记具有从预授权标注中要求的作用域,则该调用将正常工作。

回答

1

这是通过向现有的决策选民列表中添加选举人来解决的。

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

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,它将具有决策选择器的初始列表。

0

使用WebSecurity

您当前正在控制器操作中使用preauthorize规则。方法安全的力量最初是,使用它的方法而不是直接相关的路由,因为这些可以设置HttpSecurity请求匹配器,通常通过使用WebSecurityConfigurerAdapter

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

我看到解决您的需求的唯一方法是挂钩弹簧安全筛选过程并为管理范围定义特殊规则。您可以阅读here有关如何实现自定义过滤器,其中放置后您的OAuth2验证程序提取,寻找管理范围(或不同的全球性规则)

树角色

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