springcloud-oauth2 icon indicating copy to clipboard operation
springcloud-oauth2 copied to clipboard

资源服务器对 scope 作用域没有控制

Open armorsuitable opened this issue 4 years ago • 4 comments

看到在认证服务器模块, 添加 sever scope 作用域, 但在资源服务器没有区别 sever 和其他作用域怎么控制

armorsuitable avatar Mar 12 '20 03:03 armorsuitable

你好, 你说的是ResourceId配置还是客户端的scopes,scopes针对的客户端的访问权限,跟是哪个服务没有关系的。ResourceId才跟每个服务有直接的关系,假设有两个服务,一个A,一个B,他们的ResourceId分别在配置文件中配置A-server,B-server,但客户端配置的的ResourceId列表只有A-server,那当拿到token后只能访问A-server,而不能访问B-server。项目我也提交了一个scope控制的测试接口,可以更新看下。

copoile avatar Mar 12 '20 14:03 copoile

是针对客户端的访问作用域。看到最后一次提交使用了 #oauth2.hasScope('write') 这种权限表达式,想问下还有没有其他的方案,spring security 权限表达式确实用的有点难受。。

armorsuitable avatar Mar 13 '20 05:03 armorsuitable

spring security方法级别的权限控制都差不多是这样的,如果是想控制某个服务可以配置资源id,

 @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID).stateless(true);
    }
        //  资源id列表,需要注意的是这里配置的需要与ResourceServerConfig中配置的相匹配,不匹 
       // 配将权限不足
        List<String> resourceIds = new ArrayList<>();
        resourceIds.add("auth-server");
        resourceIds.add("resource-server");
        clientDetails.setResourceIds(resourceIds);

copoile avatar Mar 13 '20 08:03 copoile

可使用Spring Security 表达式中的 OAuth2WebSecurityExpressionHandler 重写 createEvaluationContextInternal 方法,定义自己的权限表达式。

@Component
public class AppSecurityExpressionHandler extends OAuth2WebSecurityExpressionHandler {

    private final PermissionService permissionService;

    @Autowired
    public AppSecurityExpressionHandler(PermissionService permissionService) {
        this.permissionService = permissionService;
    }

    @Override
    protected StandardEvaluationContext createEvaluationContextInternal(Authentication authentication, FilterInvocation invocation) {
        StandardEvaluationContext evaluationContext = super.createEvaluationContextInternal(authentication, invocation);
        evaluationContext.setVariable("permissionService", permissionService);
        return evaluationContext;
    }
}

再重写 **ResourceServerConfigurerAdapter** 中的 configure(HttpSecurity http) 方法,调用其中的access方法传入 自己定义的权限表达式,既可以控制客户端的作用域,又可以根据当前用户的身份定制对应的权限.


@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private final AppSecurityExpressionHandler expressionHandler;

    @Autowired
    public OAuth2ResourceServerConfig(AppSecurityExpressionHandler expressionHandler) {
        this.expressionHandler = expressionHandler;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.expressionHandler(expressionHandler);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/logout").permitAll()
                .anyRequest().access("#permissionService.hasPermission(request, authentication)");
    }
}

armorsuitable avatar Mar 15 '20 12:03 armorsuitable