问题描述
我正在使用Spring Security OAuth2 2.0.7.RELEASE。因为我使用ORM连接到我的数据库,默认JdbcUserDetailsManager使用jdbc我想实现我自己的UserDetailsService,这是
I am using Spring Security OAuth2 2.0.7.RELEASE. As i am using ORM to connect to my database and default JdbcUserDetailsManager uses jdbc i wanted to implement my own UserDetailsService, which is
@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;
}
}
此外,我修改了权限模式,如下所示:
Besides, i've modified authorities schema as follows:
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:
Then i am injecting my custom userDetailsService like this:
@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
}
}
如果我发送/ oauth / token请求使用grant_type =密码然后我收到此错误
If i send /oauth/token request with grant_type=password then i get this error
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被编码)
(where clientId and clientSecret is encoded)
{
"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。事实上,当我开始调试时,我发现遵循以下步骤:
Apparently is still using the default JdbcDaoImpl. In fact, when i started debugging, i found that is following these steps:
- 验证客户端(好的,因为我没有修改oauth_client_details表)
- 使用我的自定义userDetailsService验证用户(确定,用户表已修改但我的自定义userDetailsService支持更改)
- 使用默认userDetailsService验证用户(ERROR) )
我不知道为什么会这样。这对我来说听起来像个错误。
你发现有什么不对吗?
I don't know why this is happening. It sounds like a bug to me.Do you find anything wrong?
推荐答案
你正在使用 auth.jdbcAuthentication()。 dataSource(this.dataSource).and()。userDetailsService(this.userService); //注入自定义
,我在这里创建两个auth管理器 - 一个默认 JdbcDaoImpl
和 dataSource
指向 this.dataSource
,另一个带有自定义 userService
。试着把 auth.userDetailsService(this.userService)
(我希望userService已经在里面自动装配了jdbc)。
You are using auth.jdbcAuthentication().dataSource(this.dataSource).and().userDetailsService(this.userService);// Inject custom
and I here it's creating two auth managers - one with default JdbcDaoImpl
and dataSource
pointing to this.dataSource
and another with your custom userService
. Try just putting auth.userDetailsService(this.userService)
(I hope that userService already have jdbc autowired inside).
这里的要点是 .and()
用于向身份验证管理器添加不同的身份验证配置,而不是配置 jdbcAuthentication()
一个。
The point here is that .and()
is used to add different authentication configurations to the authentication manager, not configuring the jdbcAuthentication()
one.
这篇关于在Spring Security OAuth2中注入自定义userDetailsService的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!