将自定义UserDetailsService添加到Spring Security OAuth2应用
如何将下面的自定义UserDetailsService
添加到今年春季的OAuth2示例?
How do I add the custom UserDetailsService
below to this Spring OAuth2 sample?
The default user
with default password
is defined in the application.properties
file of the authserver
app.
但是,我想将以下自定义UserDetailsService
添加到
However, I would like to add the following custom UserDetailsService
to the demo
package of the authserver
app for testing purposes:
package demo;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Service;
@Service
class Users implements UserDetailsManager {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String password;
List<GrantedAuthority> auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER");
if (username.equals("Samwise")) {
auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_HOBBIT");
password = "TheShire";
}
else if (username.equals("Frodo")){
auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_HOBBIT");
password = "MyRing";
}
else{throw new UsernameNotFoundException("Username was not found. ");}
return new org.springframework.security.core.userdetails.User(username, password, auth);
}
@Override
public void createUser(UserDetails user) {// TODO Auto-generated method stub
}
@Override
public void updateUser(UserDetails user) {// TODO Auto-generated method stub
}
@Override
public void deleteUser(String username) {// TODO Auto-generated method stub
}
@Override
public void changePassword(String oldPassword, String newPassword) {
// TODO Auto-generated method stub
}
@Override
public boolean userExists(String username) {
// TODO Auto-generated method stub
return false;
}
}
如您所见,此UserDetailsService
还不是autowired
,它故意使用不安全的密码,因为它仅用于测试目的.
As you can see, this UserDetailsService
is not autowired
yet, and it purposely uses insecure passwords because it is only designed for testing purposes.
需要对 GitHub示例应用程序,以便用户可以使用password=TheShire
和username=Frodo
登录,或者使用password=MyRing
和password=MyRing
登录.是否需要对 AuthserverApplication.java
还是其他地方?
What specific changes need to be made to the GitHub sample app so that a user can login as username=Samwise
with password=TheShire
, or as username=Frodo
with password=MyRing
? Do changes need to be made to AuthserverApplication.java
or elsewhere?
建议:
Spring OAuth2开发人员指南说使用GlobalAuthenticationManagerConfigurer
全局配置UserDetailsService
.但是,使用谷歌搜索这些名称所产生的效果却不尽人意.
The Spring OAuth2 Developer Guide says to use a GlobalAuthenticationManagerConfigurer
to configure a UserDetailsService
globally. However, googling those names produces less than helpful results.
另外,使用内部弹簧安全性INSTEAD OF OAuth的其他应用程序使用以下语法来连接UserDetailsService
,但是我不确定如何将其语法调整为当前OP:
Also, a different app that uses internal spring security INSTEAD OF OAuth uses the following syntax to hook up the UserDetailsService
, but I am not sure how to adjust its syntax to the current OP:
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {
@Autowired
private Users users;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(users);
}
}
我尝试使用OAuth2AuthorizationConfig
内的@Autowire
将Users
连接到AuthorizationServerEndpointsConfigurer
,如下所示:
I tried using @Autowire
inside the OAuth2AuthorizationConfig
to connect Users
to the AuthorizationServerEndpointsConfigurer
as follows:
@Autowired//THIS IS A TEST
private Users users;//THIS IS A TEST
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.userDetailsService(users)//DetailsService)//THIS LINE IS A TEST
;
}
但是Spring Boot日志指示找不到用户Samwise
,这意味着UserDetailsService
未成功连接.以下是Spring Boot日志的相关摘录:
But the Spring Boot logs indicate that the user Samwise
was not found, which means that the UserDetailsService
was not successfully hooked up. Here is the relevant excerpt from the Spring Boot logs:
2016-04-20 15:34:39.998 DEBUG 5535 --- [nio-9999-exec-9] o.s.s.a.dao.DaoAuthenticationProvider :
User 'Samwise' not found
2016-04-20 15:34:39.998 DEBUG 5535 --- [nio-9999-exec-9]
w.a.UsernamePasswordAuthenticationFilter :
Authentication request failed:
org.springframework.security.authentication.BadCredentialsException:
Bad credentials
我还能尝试什么?
使用Spring Security开发我的oauth服务器时遇到了类似的问题.我的情况略有不同,因为我想添加UserDetailsService
来验证刷新令牌,但是我认为我的解决方案也会为您提供帮助.
I ran into a similar issue when developing my oauth server with Spring Security. My situation was slightly different, as I wanted to add a UserDetailsService
to authenticate refresh tokens, but I think my solution will help you as well.
像您一样,我首先尝试使用AuthorizationServerEndpointsConfigurer
指定UserDetailsService
,但这不起作用.我不确定这是错误还是特意设计的,但是需要在AuthenticationManager
中设置UserDetailsService
以便各种oauth2类找到它.这对我有用:
Like you, I first tried specifying the UserDetailsService
using the AuthorizationServerEndpointsConfigurer
, but this does not work. I'm not sure if this is a bug or by design, but the UserDetailsService
needs to be set in the AuthenticationManager
in order for the various oauth2 classes to find it. This worked for me:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
Users userDetailsService;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// other stuff to configure your security
}
}
我认为,如果您从第73行开始更改了以下内容,则可能对您有用:
I think if you changed the following starting at line 73, it may work for you:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
您当然还需要在WebSecurityConfigurerAdapter
我想提及的其他内容:
- 这可能是特定于版本的,我使用的是spring-security-oauth2 2.0.12
- 我无法引用任何消息来说明为什么会这样,我什至不确定我的解决方案是真正的解决方案还是黑客.
- 该指南中提到的
GlobalAuthenticationManagerConfigurer
几乎可以肯定是一个错字,在Spring的任何源代码中我都找不到该字符串.
- This may be version specific, I'm on spring-security-oauth2 2.0.12
- I can't cite any sources for why this is the way it is, I'm not even sure if my solution is a real solution or a hack.
- The
GlobalAuthenticationManagerConfigurer
referred to in the guide is almost certainly a typo, I can't find that string anywhere in the source code for anything in Spring.