我正在使用 Spring Security OAuth2 2.0.7.RELEASE。由于我使用 ORM 连接到我的数据库并且默认 JdbcUserDetailsManager 使用 jdbc 我想实现我自己的 UserDetailsService,即
@Service
public class UserService
implements UserDetailsService {
@Override
public UserDetailsService loadUserByUsername(String username) throws UsernameNotFoundException {
// I tested this logic and works fine so i avoid this lines
return userDetailsService;
}
}
此外,我还修改了权限架构如下:
mysql> describe authorities;
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| authority_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| user_id | bigint(20) unsigned | NO | MUL | NULL | |
| authority | varchar(256) | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
然后我像这样注入我的自定义 userDetailsService :
@Configuration
@Import(OAuth2SupportConfig.class)
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends
AuthorizationServerConfigurerAdapter {
...
@Autowired
private UserDetailsService userDetailsService
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore).tokenServices(tokenService);
endpoints.userDetailsService(userDetailsService); // Inject custom
endpoints.authorizationCodeServices(authorizationCodeServices);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.jdbc(dataSource);
}
}
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthenticationManagerConfiguration
extends GlobalAuthenticationConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private UserDetailsService userService;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(this.dataSource).and().userDetailsService(this.userService);// Inject custom
}
}
如果我使用 grant_type=password 发送 /oauth/token 请求,则会收到此错误
POST /oauth/token HTTP/1.1
Host: localhost:8080
Authorization: Basic aW5kaXJhOnNlY3JldA==
Cache-Control: no-cache
Postman-Token: c89baf37-8ad2-4270-5251-9715bfab470a
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=user&password=pass
(其中对 clientId 和 clientSecret 进行编码)
{
"error": "unauthorized",
"error_description": "PreparedStatementCallback; bad SQL grammar [select username,authority from authorities where username = ?]; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'username' in 'field list'"
}
显然仍然使用默认的JdbcDaoImpl。事实上,当我开始调试时,我发现遵循以下步骤:
- 验证客户端(好的,因为我没有修改 oauth_client_details 表)
- 使用我的自定义 userDetailsService 对用户进行身份验证(好的,用户表已修改,但我的自定义 userDetailsService 支持更改)
- 使用默认的 userDetailsService 对用户进行身份验证(错误)
我不知道为什么会发生这种情况。对我来说这听起来像是一个错误。
你有没有发现什么问题?