spring - TokenEndpoint : Handling error: InvalidGrantException, Bad credentials with right credentials
问题描述
I am currently working on my own project which should have its own oauth authentication server using spring-boot and spring-oauth.
I get
TokenEndpoint : Handling error: InvalidGrantException, Bad credentials even the name and password are right.
I save my users in mysql and encode the passwords with bCrypt
.
Below are my configurations
I tried:
- {noop} in password
- tried different implementations of the passwordEncoder Bean
- tried to use a Custom UserDetailsServiceImplementation
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
/**
* Setting up the endpointsconfigurer authentication manager.
* The AuthorizationServerEndpointsConfigurer defines the authorization and token endpoints and the token services.
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenStore(getTokenStore());
}
@Bean
public TokenStore getTokenStore(){
return new InMemoryTokenStore();
}
/**
* Setting up the clients with a clientId, a clientSecret, a scope, the grant types and the authorities.
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password")
.authorities("ROLE_USER").scopes("read","write","trust")
.resourceIds("oauth2-resource").accessTokenValiditySeconds(5000).secret(passwordEncoder.encode("secret"));
}
/**
* We here defines the security constraints on the token endpoint.
* We set it up to isAuthenticated, which returns true if the user is not anonymous
* @param security the AuthorizationServerSecurityConfigurer.
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
}
public class CustomUserDetails implements UserDetails {
private String password;
private String username;
private Collection<? extends GrantedAuthority> authorities;
public CustomUserDetails(User user) {
this.username = user.getUsername();
this.password = user.getPassword();
this.authorities = translate(user.getRole());
}
private Collection<? extends GrantedAuthority> translate(Role role) {
List<GrantedAuthority> authorities = new ArrayList<>();
String roleName = role.getRole().toUpperCase();
authorities.add(new SimpleGrantedAuthority(roleName));
return authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","/home","/register","/login").permitAll()
.antMatchers("/private/**").authenticated()
.antMatchers("/post").authenticated()
.antMatchers("/post/postComment").authenticated()
.antMatchers(HttpMethod.DELETE , "/post/**").hasAuthority("ROLE_ADMIN");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@SpringBootApplication
@EnableAuthorizationServer
public class BackendApplication {
@Autowired
private PasswordEncoder passwordEncoder;
public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* Password grants are switched on by injecting an AuthenticationManager.
* Here, we setup the builder so that the userDetailsService is the one we coded.
* @param builder
* @param repository
* @throws Exception
*/
@Autowired
public void authenticationManager(AuthenticationManagerBuilder builder, UserRepository repository, UserService userService) throws Exception {
if (repository.count()==0) {
userService.save(new User("admin", "{noop}adminPassword", new Role("ROLE_USER")));
}
builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder);
}
/**
* We return an istance of our CustomUserDetails.
* @param repository
* @return
*/
private UserDetailsService userDetailsService(final UserRepository repository) {
return username -> new CustomUserDetails(repository.findByUsername(username));
}
}
Warning Message: 2019-07-24 15:46:42.341 WARN 73936 --- [nio-8088-exec-4] o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: InvalidGrantException, Bad credentials
URL: http://localhost:8088/oauth/token The Request is url-www-form-encoded with the Parameters:
- grant_type:password
- username:admin
- password:adminPassword
and "Basic Auth" with Username "my-trusted-client" and Password "secret".
解决方案
用于 .secret("{bcrypt}" + passwordEncoder.encode("secret"))
my-trusted-client 和.secret("{bcrypt}" + passwordEncoder.encode("adminPassword"))
admin。并且:检查 BcryptPasswordEncoder 是否在调试会话中使用。
推荐阅读
- image-processing - 在此示例中,相关性如何对偶数大小的过滤器起作用?
- java - 模式匹配器返回意外值
- excel - VBA如何动态生成选项按钮的名称?
- css - 你如何使文本输入边框重叠?
- elasticsearch - GKE 上的 Elasticsearch - 无法使用 gcs 插件配置快照和还原
- apache-spark - 高效的 Spark JSON 转换
- node.js - 在 Gatsby 构建期间检索文件内容
- elasticsearch-2.0 - 如何在elasticsearch中构建促销数据
- reactjs - 单击时反应模态图像不显示大尺寸图像
- javascript - 如何根据同一段落中的语言更改字体?