问题
I have a requirement where I want to list the api methods in swagger based on user roles.
For example :-
- User A with basic access can use limited api methods.
- User B with Admin access can use all the listed api methods.
I don't know how to achieve this.
I am using Swashbuckle.AspNetCore Version="1.0.0"
回答1:
Try using an IDocumentFilter, you can limit what the user gets in the SwaggerDocument and the swagger-ui feeds from that.
Here are some examples https://github.com/heldersepu/SwashbuckleTest/blob/master/Swagger_Test/App_Start/SwaggerConfig.cs#L261
回答2:
Possible solution:
- Define several dockets in your swagger config with different group names
@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());
}
- Define your own
DocumentationCache
which overrides Swagger's one
@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
}
}
So this cache will return groups based on the current user's role from the security context. You can actually use any rules to restrict access to different groups.
Also do not forget to define proper permissions for HttpSecurity
to restrict the invocation of an API for not allowed roles.
来源:https://stackoverflow.com/questions/44904213/list-the-api-in-swagger-based-on-user-roles