@EnableResourceServer与@EnableAuthorizationServer已废弃?OAuth配置替代方案咨询
Hey there! Those two annotations (@EnableResourceServer and @EnableAuthorizationServer) were indeed phased out starting with Spring Security 5.x, replaced by a more modular, integrated approach built directly into Spring Security's core OAuth2 support. Let's walk through the modern way to set up both servers.
1. Authorization Server Setup
Instead of the old @EnableAuthorizationServer, you'll now use the Spring Security OAuth2 Authorization Server module. Here's how to get started:
Step 1: Add Dependency
First, include the authorization server starter in your pom.xml (Maven) or build.gradle (Gradle):
<!-- Maven --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-authorization-server</artifactId> <version>1.2.3</version> <!-- Use the latest stable version --> </dependency>
Step 2: Configure the Authorization Server
Create a configuration class to define core components like registered clients, user details, and security filters:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @Configuration @EnableWebSecurity public class AuthorizationServerConfig { @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .oidc(oidc -> oidc.clientRegistrationEndpoint(clientRegistration -> clientRegistration)); // Enable OIDC if needed // Redirect unauthenticated users to login page http.exceptionHandling(exceptions -> exceptions .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))); return http.build(); } @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient testClient = RegisteredClient.withId("test-client-id") .clientId("test-client") .clientSecret(passwordEncoder().encode("test-secret")) .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .redirectUri("http://localhost:8080/login/oauth2/code/test-client") .scope(OidcScopes.OPENID) .scope("read") .scope("write") .build(); return new InMemoryRegisteredClientRepository(testClient); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public UserDetailsService userDetailsService() { UserDetails testUser = User.withUsername("test-user") .password(passwordEncoder().encode("test-password")) .roles("USER") .build(); return username -> testUser; } }
Note: Swap in-memory repositories for JDBC implementations in production for persistent client/user storage.
2. Resource Server Setup
For the resource server, instead of @EnableResourceServer, you'll use @EnableWebSecurity and configure the OAuth2 resource server filter chain directly:
Step 1: Add Dependency
Ensure you have the Spring Security OAuth2 resource server starter:
<!-- Maven --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency>
Step 2: Configure the Resource Server
Create a configuration class to secure your endpoints and validate tokens:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class ResourceServerConfig { @Bean public SecurityFilterChain resourceServerSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .issuerUri("http://localhost:8080") // Point to your authorization server's issuer URI ) ); return http.build(); } }
If using opaque tokens instead of JWT, replace .jwt(...) with .opaqueToken(opaque -> opaque.introspectionUri("http://localhost:8080/oauth2/introspect")) and configure client credentials for token introspection.
Key Takeaways
- The new setup integrates seamlessly with Spring Security's core features (method security, CORS, CSRF, etc.)
- If your auth server and resource server are in the same app, reuse the
JwtDecoderbean from the auth server instead of specifying the issuer URI - Always use persistent storage for production setups
内容的提问来源于stack exchange,提问作者rakesh mehra

