Spring Boot 2.0 M7下OAuth2服务器配置与JWT数据库客户端实现问询
Hey there, I totally get the frustration when milestone versions break existing code—Spring Boot 2.0 M7 had a few tweaks from M4 that make those older examples incompatible. Let's walk through both your questions with working, M7-specific code.
First, you'll need to set up the right dependencies and enable the authorization server. Since M7 is a milestone release, don't forget to include the Spring Milestones repository in your build file.
Step 1: Add Dependencies (Maven Example)
<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.0.0.M7</version> </dependency> </dependencies>
Step 2: Authorization Server Config
Create a config class annotated with @EnableAuthorizationServer and extend AuthorizationServerConfigurerAdapter to set up clients and security rules:
import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; @Configuration @EnableAuthorizationServer public class BasicOAuth2ServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { // Allow public access to the token endpoint (for password flow testing) security.tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // In-memory client setup for quick testing clients.inMemory() .withClient("test-client") .secret("{noop}test-secret") // {noop} disables password encoding (only for testing!) .authorizedGrantTypes("password", "refresh_token") .scopes("read", "write") .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(86400); } }
Step 3: Web Security Config
You need to set up user authentication for the password grant flow:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // In-memory user for testing auth.inMemoryAuthentication() .withUser("test-user") .password("{noop}test-pass") .roles("USER"); } @Bean public PasswordEncoder passwordEncoder() { // WARNING: Use BCryptPasswordEncoder in production! This is only for testing. return NoOpPasswordEncoder.getInstance(); } }
For this, we'll replace the in-memory client store with a database-backed one, and add JWT token support.
Step 1: Add Database Dependency
Update your Maven pom to include JDBC and a database driver (H2 for testing):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>
Step 2: Set Up Client Database Table
Spring OAuth2 uses a default table structure for client details. Create this table in your database:
CREATE TABLE oauth_client_details ( client_id VARCHAR(256) PRIMARY KEY, resource_ids VARCHAR(256), client_secret VARCHAR(256), scope VARCHAR(256), authorized_grant_types VARCHAR(256), web_server_redirect_uri VARCHAR(256), authorities VARCHAR(256), access_token_validity INTEGER, refresh_token_validity INTEGER, additional_information VARCHAR(4096), autoapprove VARCHAR(256) ); -- Insert a test client (use encrypted password in production!) INSERT INTO oauth_client_details (client_id, client_secret, scope, authorized_grant_types, access_token_validity, refresh_token_validity) VALUES ('db-client', '{noop}db-secret', 'read,write', 'password,refresh_token', 3600, 86400);
Step 3: Authorization Server Config with JWT + DB Clients
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import javax.sql.DataSource; @Configuration @EnableAuthorizationServer public class JwtDbOAuth2ServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private DataSource dataSource; @Bean public ClientDetailsService clientDetailsService() { // Use JDBC to fetch client details from the database return new org.springframework.security.oauth2.provider.client.JdbcClientDetailsService(dataSource); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // Use a strong signing key in production (e.g., RSA key pair) converter.setSigningKey("your-strong-signing-key"); return converter; } @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public DefaultTokenServices tokenServices() { DefaultTokenServices services = new DefaultTokenServices(); services.setClientDetailsService(clientDetailsService()); services.setTokenStore(tokenStore()); services.setSupportRefreshToken(true); services.setAccessTokenConverter(accessTokenConverter()); return services; } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // Use the database-backed client details service clients.withClientDetails(clientDetailsService()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore()) .accessTokenConverter(accessTokenConverter()) .tokenServices(tokenServices()); } }
Key Notes for Production
- Password Encoding: Replace
NoOpPasswordEncoderwithBCryptPasswordEncoder(or another strong encoder) for both client secrets and user passwords. Store encrypted values in the database instead of plain text. - JWT Signing: Use an RSA key pair instead of a simple string for signing JWT tokens. You can load keys from files or environment variables.
- Dependencies: Ensure all Spring Security OAuth2 dependencies are on version 2.0.0.M7 to avoid compatibility issues.
内容的提问来源于stack exchange,提问作者Juan Pablo

