我正在尝试创建一个实现oauth2.0的项目。我正在使用Springboot 2,我的客户端存储在JDBC中,并使用JWT令牌存储。
该应用程序运行,但是当我向/ oauth / token发送POST请求时,出现内部服务器错误。我尝试调试代码,似乎UserDetailsService委托人正在委托自己,造成了堆栈溢出错误。
这是我的授权服务器:
@Configuration @EnableAuthorizationServer @EnableConfigurationProperties(SecurityProperties.class) public class AuthorizationServerConfiguration
extends AuthorizationServerConfigurerAdapter
{
@Autowired private PasswordEncoder passwordEncoder;
@Autowired private AuthenticationManager authenticationManager;
@Autowired private UserDetailsService userDetailsService;
@Autowired private SecurityProperties securityProperties;
JwtAccessTokenConverter jwtAccessTokenConverter;
TokenStore tokenStore;
@Bean
public TokenStore tokenStore()
{
if(tokenStore == null)
{
tokenStore = new JwtTokenStore(accessTokenConverter());
}
return tokenStore;
}
@Bean
public DefaultTokenServices tokenServices(final TokenStore tokenStore, final ClientDetailsService clientDetailsService)
{
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setAuthenticationManager(this.authenticationManager);
return tokenServices;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter()
{
if(jwtAccessTokenConverter != null)
{
return jwtAccessTokenConverter;
}
SecurityProperties.JwtProperties jwtProperties = securityProperties.getJwt();
KeyPair keyPair = keyPair(jwtProperties, keyStoreKeyFactory(jwtProperties));
jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setKeyPair(keyPair);
jwtAccessTokenConverter.setSigningKey("montyKey");
return jwtAccessTokenConverter;
}
@Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/OauthTestDB?useSSL=false");
dataSource.setUsername("root");
dataSource.setPassword("MyPassword99");
return dataSource;
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception
{
clients.jdbc(dataSource());
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints)
{
endpoints.authenticationManager(this.authenticationManager)
.accessTokenConverter(accessTokenConverter())
.userDetailsService(this.userDetailsService)
.tokenStore(tokenStore());
}
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer)
{
oauthServer.passwordEncoder(this.passwordEncoder)
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
private KeyPair keyPair(SecurityProperties.JwtProperties jwtProperties, KeyStoreKeyFactory keyStoreKeyFactory)
{
return keyStoreKeyFactory.getKeyPair(jwtProperties.getKeyPairAlias(), jwtProperties.getKeyPairPassword().toCharArray());
}
private KeyStoreKeyFactory keyStoreKeyFactory(SecurityProperties.JwtProperties jwtProperties)
{
return new KeyStoreKeyFactory(jwtProperties.getKeyStore(), jwtProperties.getKeyStorePassword().toCharArray());
}
}
WebSecurityConfiguration:
@EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
{
private PasswordEncoder passwordEncoder;
private UserDetailsService userDetailsService;
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder()
{
if(passwordEncoder == null)
{
passwordEncoder = DefaultPasswordEncoderFactories.createDelegatingPasswordEncoder();
}
return passwordEncoder;
}
@Bean
public UserDetailsService userDetailsService(DataSource dataSource)
{
if(userDetailsService == null)
{
userDetailsService = new JdbcDaoImpl();
((JdbcDaoImpl) userDetailsService).setDataSource(dataSource);
}
return userDetailsService;
}
}
错误日志如下:
[DEBUG] 2019-07-17 10:40:09.326 [http-nio-9000-exec-1] FilterChainProxy - /oauth/token?grant_type=password&username=user&password=pass reached end of additional filter chain; proceeding with original chain
[DEBUG] 2019-07-17 10:40:09.327 [http-nio-9000-exec-1] DispatcherServlet - POST "/oauth/token?grant_type=password&username=user&password=pass", parameters={masked}
[DEBUG] 2019-07-17 10:40:09.332 [http-nio-9000-exec-1] FrameworkEndpointHandlerMapping - Mapped to public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
[DEBUG] 2019-07-17 10:40:09.339 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL query
[DEBUG] 2019-07-17 10:40:09.339 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL statement [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]
[DEBUG] 2019-07-17 10:40:09.339 [http-nio-9000-exec-1] DataSourceUtils - Fetching JDBC Connection from DataSource
[DEBUG] 2019-07-17 10:40:09.339 [http-nio-9000-exec-1] DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/OauthTestDB?useSSL=false]
[DEBUG] 2019-07-17 10:40:09.345 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL query
[DEBUG] 2019-07-17 10:40:09.345 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL statement [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]
[DEBUG] 2019-07-17 10:40:09.345 [http-nio-9000-exec-1] DataSourceUtils - Fetching JDBC Connection from DataSource
[DEBUG] 2019-07-17 10:40:09.345 [http-nio-9000-exec-1] DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/OauthTestDB?useSSL=false]
[DEBUG] 2019-07-17 10:40:09.354 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL query
[DEBUG] 2019-07-17 10:40:09.354 [http-nio-9000-exec-1] JdbcTemplate - Executing prepared SQL statement [select client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove from oauth_client_details where client_id = ?]
[DEBUG] 2019-07-17 10:40:09.354 [http-nio-9000-exec-1] DataSourceUtils - Fetching JDBC Connection from DataSource
[DEBUG] 2019-07-17 10:40:09.354 [http-nio-9000-exec-1] DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/OauthTestDB?useSSL=false]
[DEBUG] 2019-07-17 10:40:09.359 [http-nio-9000-exec-1] ResourceOwnerPasswordTokenGranter - Getting access token for: clientId
[DEBUG] 2019-07-17 10:40:09.359 [http-nio-9000-exec-1] ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
[DEBUG] 2019-07-17 10:40:09.422 [http-nio-9000-exec-1] ExceptionHandlerExceptionResolver - Using @ExceptionHandler public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.exceptions.OAuth2Exception> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.handleException(java.lang.Exception) throws java.lang.Exception
[WARN ] 2019-07-17 10:40:09.423 [http-nio-9000-exec-1] TokenEndpoint - Handling error: NestedServletException, Handler dispatch failed; nested exception is java.lang.StackOverflowError
[DEBUG] 2019-07-17 10:40:09.436 [http-nio-9000-exec-1] HttpEntityMethodProcessor - Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
[DEBUG] 2019-07-17 10:40:09.436 [http-nio-9000-exec-1] HttpEntityMethodProcessor - Writing [error="server_error", error_description="Internal Server Error"]
答案 0 :(得分:0)
我最终只是删除了以下配置:
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}