【问题标题】:list the api in swagger based on user roles根据用户角色swagger列出api
【发布时间】:2017-12-07 19:44:54
【问题描述】:

我有一个需求,我想根据用户角色在 swagger 中列出 api 方法。

例如:-

  • 具有基本访问权限的用户 A 可以使用有限的 api 方法。
  • 具有管理员权限的用户 B 可以使用所有列出的 api 方法。

我不知道如何实现。

我正在使用Swashbuckle.AspNetCore Version="1.0.0"

【问题讨论】:

  • 自您发布此问题已有 2 年。无论如何,你有没有找到实现这一目标的方法?
  • 检查我发布的解决方案。希望这会有所帮助。

标签: api swagger swagger-ui user-roles swashbuckle


【解决方案1】:

可能的解决方案:

  1. 在您的 swagger 配置中使用不同的组名定义多个文档
@Bean
public Docket api1() {
    ...
    return new Docket(DocumentationType.SWAGGER_2)
            ...
            .groupName("api1")
            ...
            .paths(PathSelectors.ant("/api/api1Url/**"))
            .build().apiInfo(metaData());
}

@Bean
public Docket api2() {
    ...
    return new Docket(DocumentationType.SWAGGER_2)
            ...
            .groupName("api2")
            ...
            .paths(PathSelectors.ant("/api/api2Url/**"))
            .build().apiInfo(metaData());
}
  1. 定义您自己的DocumentationCache,它会覆盖 Swagger 的@
@Primary
@Component
public class RolesAwareDocumentationCache extends DocumentationCache {

    private final Map<String, Set<String>> allowedResourcesPerRole =
            Map.of(SecurityConfig.API1_ROLE, Collections.singleton("api1"),
                    SecurityConfig.API2_ROLE, Collections.singleton("api2"),
                    SecurityConfig.SOME_ADMIN_ROLE, Set.of("api1", "api2"));

    @Override
    public Map<String, Documentation> all() {
        var documentationMap = super.all();
        return documentationMap.entrySet().stream()
                .filter(e -> isAllowedForRole(e.getKey())) // check if has access to this group
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }

    private boolean isAllowedForRole(String groupName) {
        var userAuthorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream()
                .map(Object::toString)
                .collect(Collectors.toUnmodifiableSet());

        return userAuthorities.stream()
                .map(allowedResourcesPerRole::get) // get allowed resources for all of the user roles
                .filter(Objects::nonNull)
                .flatMap(Collection::stream) // flatMap to collection
                .anyMatch(s -> s.contains(groupName)); // check if result collection has specified group name
    }

}

因此,此缓存将根据安全上下文中当前用户的角色返回组。您实际上可以使用任何规则来限制对不同组的访问。

同时不要忘记为HttpSecurity 定义适当的权限,以限制对不允许的角色调用 API。

【讨论】:

    【解决方案2】:

    尝试使用 IDocumentFilter,您可以限制用户在 SwaggerDocument 和 swagger-ui 中获取的内容。

    这里有一些例子https://github.com/heldersepu/SwashbuckleTest/blob/master/Swagger_Test/App_Start/SwaggerConfig.cs#L261

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-03
      • 2022-10-23
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多