如何让Spring Security列出Spring MVC应用所有URL及其安全配置?
Great question! When you're managing a large Spring MVC app with 100+ endpoints scattered across controllers, keeping track of which ones have proper @PreAuthorize annotations can feel like a chore. The good news is Spring does store all that endpoint and security metadata internally—you just need to know how to access it. Here are practical approaches to get a complete list of your URLs and their associated security rules:
1. Build a Custom Auditor Component (Most Straightforward)
Spring exposes two key beans that let you map endpoints to their security rules:
RequestMappingHandlerMapping: Holds all your MVC endpoint mappings (URLs, HTTP methods, and the controller methods they map to)MethodSecurityMetadataSource: Stores the security metadata (like@PreAuthorizeexpressions) for every secured method
You can wire these together into a component that runs on app startup to print or export a full audit report:
import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.method.MethodSecurityMetadataSource; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.condition.RequestMappingInfo; import org.springframework.web.method.HandlerMethod; import javax.annotation.PostConstruct; import java.util.Collection; import java.util.Map; @Component public class EndpointSecurityAuditor { private final RequestMappingHandlerMapping requestMappingHandlerMapping; private final MethodSecurityMetadataSource methodSecurityMetadataSource; // Constructor injection (works with Spring 4.3+) public EndpointSecurityAuditor(RequestMappingHandlerMapping requestMappingHandlerMapping, MethodSecurityMetadataSource methodSecurityMetadataSource) { this.requestMappingHandlerMapping = requestMappingHandlerMapping; this.methodSecurityMetadataSource = methodSecurityMetadataSource; } @PostConstruct public void generateSecurityAudit() { Map<RequestMappingInfo, HandlerMethod> allEndpoints = requestMappingHandlerMapping.getHandlerMethods(); System.out.println("=== Spring MVC Endpoint Security Audit ==="); for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : allEndpoints.entrySet()) { RequestMappingInfo mapping = entry.getKey(); HandlerMethod handlerMethod = entry.getValue(); // Get security rules for the method Collection<ConfigAttribute> securityAttributes = methodSecurityMetadataSource.getAttributes( handlerMethod.getMethod(), handlerMethod.getBeanType() ); // Print details System.out.println("\nEndpoint URL(s): " + mapping.getPatternsCondition().getPatterns()); System.out.println("HTTP Methods: " + mapping.getMethodsCondition().getMethods()); System.out.println("Controller Method: " + handlerMethod.getMethod().toGenericString()); System.out.println("Security Rule: " + (securityAttributes != null ? securityAttributes : "NO SECURITY ANNOTATION - UNPROTECTED!")); } } }
When your app starts, this will print a full breakdown of every endpoint, including which ones are missing security annotations (marked as UNPROTECTED!). You can tweak this to export to a file or database for easier auditing.
2. Enable Debug Logging for Spring Security
If you don't want to write custom code, you can turn on debug logging for specific Spring Security packages to get the same info in your logs. Add these properties to your application.properties or application.yml:
# Log method-level security metadata logging.level.org.springframework.security.method=DEBUG # Log URL-level security interception rules logging.level.org.springframework.security.web.access.intercept=DEBUG
When your app starts, you'll see log entries like:
DEBUG org.springframework.security.method.annotation.MethodSecurityMetadataSourceAdvisor - Adding security method metadata for method: public org.springframework.http.ResponseEntity<java.util.List
> com.yourpackage.YourController.loadConfigurations()
DEBUG org.springframework.security.method.annotation.PreAuthorizeAnnotationSecurityMetadataSource - Adding attributes for method [loadConfigurations]: [@accessChecker.canViewBusinessData(authentication)]
This will show you exactly which methods have @PreAuthorize rules, and which ones don't.
3. Use Static Code Analysis for Ongoing Checks
To prevent future missing annotations, add a static code analysis rule to your build process. Tools like SonarQube or custom rules with Checkstyle/PMD can flag any controller methods with @GetMapping/@PostMapping (or other request mappings) that don't have a @PreAuthorize (or @Secured) annotation.
For example, a simple SonarQube custom rule can scan all controller classes and enforce that every request-mapped method has a security annotation. This catches missing rules early, before they make it to production.
4. Leverage Spring Boot Actuator (For Endpoint Mappings)
If you're using Spring Boot, enable the Actuator mappings endpoint to get a list of all your endpoints (without security rules, but useful for cross-referencing):
- Add Actuator dependency to your pom.xml/build.gradle
- Enable the mappings endpoint in
application.properties:management.endpoints.web.exposure.include=mappings - Visit
http://your-app-url/actuator/mappingsto see all endpoints, their HTTP methods, and controller methods. You can cross-reference this list with your security audit from the first two methods to spot gaps.
These methods will help you fully audit your existing endpoints and keep tabs on new ones as you add them.
内容的提问来源于stack exchange,提问作者Geoffrey De Vylder

