基于用户角色的Swagger认证配置与接口权限展示问题(Spring Boot Java7)
Hey there! Let's walk through how to solve both your Swagger role-based authentication and interface visibility requirements for your Java 7 Spring Boot project. I've worked with similar setups before, so here's a step-by-step breakdown that should fit your needs.
1. Adding Role-Based Authentication to Swagger
First, we need to configure Swagger to recognize your security scheme (I'll use JWT as an example, but this works for Basic Auth too) and enforce role checks on your API paths. Since you're on Java 7, we'll use Springfox Swagger 2 (version 2.9.2 is fully compatible with Java 7 and Spring Boot 1.x).
Step 1: Add Dependencies
Add these to your pom.xml (for Maven):
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
Step 2: Configure Swagger Security
Create a SwaggerConfig class to set up the security scheme and bind it to your API paths:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.yourpackage.controller")) .paths(PathSelectors.any()) .build() .securitySchemes(Collections.singletonList(apiKey())) .securityContexts(Collections.singletonList(securityContext())); } // Define the JWT security scheme private ApiKey apiKey() { return new ApiKey("JWT", "Authorization", "header"); } // Bind the security scheme to all /api paths private SecurityContext securityContext() { return SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("/api/.*")) .build(); } private List<SecurityReference> defaultAuth() { AuthorizationScope scope = new AuthorizationScope("global", "access all endpoints"); AuthorizationScope[] scopes = new AuthorizationScope[1]; scopes[0] = scope; return Collections.singletonList(new SecurityReference("JWT", scopes)); } }
Step 3: Annotate Endpoints with Roles
Use @ApiOperation to link roles to your endpoints, and @PreAuthorize to enforce the role check via Spring Security:
@RestController @RequestMapping("/api") public class MyController { @ApiOperation( value = "Fetch admin-only data", authorizations = { @Authorization(value = "JWT", scopes = { @AuthorizationScope(scope = "admin", description = "Admin exclusive access") }) } ) @PreAuthorize("hasRole('ADMIN')") @GetMapping("/admin/data") public String getAdminData() { return "Sensitive admin information"; } @ApiOperation( value = "Fetch user-specific data", authorizations = { @Authorization(value = "JWT", scopes = { @AuthorizationScope(scope = "user", description = "Regular user access") }) } ) @PreAuthorize("hasRole('USER')") @GetMapping("/user/data") public String getUserData() { return "User's personal data"; } }
2. Showing Only Role-Allowed Interfaces in Swagger-UI
Now, we need to dynamically filter which endpoints appear in Swagger-UI based on the logged-in user's roles. Since Java 7 doesn't support lambdas, we'll use anonymous classes to build a custom selector.
Step 1: Add a Utility to Get Current User's Roles
First, add a helper method to fetch the authenticated user's roles from Spring Security:
private Collection<? extends GrantedAuthority> getCurrentUserRoles() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth == null || !auth.isAuthenticated()) { return Collections.emptyList(); } return auth.getAuthorities(); }
Step 2: Customize Swagger to Filter Endpoints
Update your Docket configuration in SwaggerConfig to use a custom RequestHandlerSelector that checks if the user has the required role for each endpoint:
@Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(new RequestHandlerSelector() { @Override public boolean apply(RequestHandler input) { // Allow public endpoints (no @PreAuthorize annotation) PreAuthorize preAuthorize = input.getMethodAnnotation(PreAuthorize.class); if (preAuthorize == null) { return true; } // Extract the required role from @PreAuthorize (e.g., "hasRole('ADMIN')" → "ADMIN") String requiredRole = preAuthorize.value() .replace("hasRole('", "") .replace("')", ""); // Check if the current user has the required role Collection<? extends GrantedAuthority> userRoles = getCurrentUserRoles(); for (GrantedAuthority authority : userRoles) { if (authority.getAuthority().equals("ROLE_" + requiredRole)) { return true; } } return false; } }) .paths(PathSelectors.any()) .build() .securitySchemes(Collections.singletonList(apiKey())) .securityContexts(Collections.singletonList(securityContext())); }
Step 3: Allow Swagger UI Access in Spring Security
Make sure your SecurityConfig permits unauthenticated access to Swagger UI resources:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() // Allow Swagger UI paths without auth .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/v2/api-docs", "/webjars/**").permitAll() // Require auth for all other paths .anyRequest().authenticated() .and() // Use your preferred auth method (JWT, Basic Auth, etc.) .httpBasic(); } }
How It Works
- When a user logs into Swagger-UI, they'll enter their auth credentials (e.g., Basic Auth username/password or JWT token).
- Swagger will fetch the user's roles from Spring Security.
- The custom selector will only include endpoints where the user has the required role (defined via
@PreAuthorize). - Admin users will see all endpoints, while regular users will only see their allowed ones.
内容的提问来源于stack exchange,提问作者D Satish Kumar Achary

