Java 迁移到Spring Boot 2-安全编码密码看起来不像BCrypt
我有一个Spring Boot 1.5.9授权服务器,它使用BCrypt存储密码。我正在尝试迁移到2.0,但是,我无法再检索用于授权的令牌 来自服务器的响应是:Java 迁移到Spring Boot 2-安全编码密码看起来不像BCrypt,java,spring,spring-boot,spring-security,Java,Spring,Spring Boot,Spring Security,我有一个Spring Boot 1.5.9授权服务器,它使用BCrypt存储密码。我正在尝试迁移到2.0,但是,我无法再检索用于授权的令牌 来自服务器的响应是: "timestamp": "2018-03-09T15:22:06.576+0000", "status": 401, "error": "Unauthorized", "message": "Unauthorized", "path": "/oauth/token" } 控制台输出以下内容:2
"timestamp": "2018-03-09T15:22:06.576+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/oauth/token"
}
控制台输出以下内容:2018-03-09 09:22:06.553警告20976---[nio-8090-exec-1]o.s.s.c.bcrypt.BCryptPasswordEncoder:编码的密码看起来不像bcrypt
这个应用程序以前工作得很好。我所做的唯一更改是build.gradle文件(更改springBootVersion
,添加io.spring.dependency management
插件,并添加运行时('org.springframework.boot:spring boot devtools')
在中散列密码的逻辑可在两个单独的配置文件中找到:
package com.midamcorp.auth_server.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.midamcorp.auth_server.service.OAuthUserDetailsService;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private OAuthUserDetailsService userService;
@Autowired
private PasswordEncoder passwordEncoder;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
// Hash password
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.realmName("test")
.and()
.csrf()
.disable();
}
}
及
OAuthUser类:
package com.midamcorp.auth_server.model;
import java.util.List;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name="auth_user")
public class OAuthUser {
// @Autowired
// @Transient
// private PasswordEncoder passwordEncoder;
//
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name= "username")
private String userName;
@Column(name="password")
@JsonIgnore
private String password;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email")
private String email;
@Column(name="is_enabled")
private boolean isEnabled;
/**
* Reference: https://github.com/nydiarra/springboot-jwt/blob/master/src/main/java/com/nouhoun/springboot/jwt/integration/domain/User.java
* Roles are being eagerly loaded here because
* they are a fairly small collection of items for this example.
*/
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns
= @JoinColumn(name = "user_id",
referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id",
referencedColumnName = "id"))
private List<Role> roles;
public OAuthUser() {};
public OAuthUser(String firstName, String lastName, String user, String pass) {
this.firstName = firstName;
this.lastName = lastName;
this.userName = user;
this.password = pass;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
}
当我使用新的用户名和密码发送请求时,我仍然收到错误
编辑两个:
请求错误的结果:
curl --request POST \
--url http://web:secret@localhost:8090/oauth/token \
--header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
--form grant_type=password \
--form username=KLM \
--form password=L
授权服务器配置:
package com.midamcorp.auth_server.config;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
// Reference: https://dazito.com/java/spring-boot-and-oauth2-with-jdbc
@EnableAuthorizationServer
@Configuration
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter{
@Autowired
private TokenStore tokenStore;
@Autowired
private AccessTokenConverter converter;
private final AppConfig appConfig;
private AuthenticationManager authenticationManager;
@Autowired
public AuthServerConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
this.authenticationManager = authenticationManager;
this.appConfig = appConfig;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("permitAll()");
security.tokenKeyAccess("permitAll()");
}
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
JdbcClientDetailsService details = new JdbcClientDetailsService(appConfig.dataSource());
configurer.jdbc(appConfig.dataSource());
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
endpoints.tokenStore(tokenStore)
.accessTokenConverter(converter)
.authenticationManager(authenticationManager);
}
@Bean
@Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
我正在使用以下属性:
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=API
spring.datasource.username=**
spring.datasource.password=**
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
server.port=8090
我用clientSecret密码解决了这个问题
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(clientId)
.secret(encode(clientSecret))
.authorizedGrantTypes(grantType)
.scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds);
}
当oauth2 Dependencies迁移到云计算时,我开始面临这个问题
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId></dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
希望这会对你有所帮助。只是因为这些记录可能会对其他人有所帮助。我也有类似的问题,我注意到了
passwordEncoder.encode(rawPassword, hashedPassword)
输入参数的顺序很重要。第一个参数应该是rawPassword,第二个参数应该是hashedPassword。我出现这个问题是因为我交换了输入参数序列。@dur Sure,“L”的值(上面插入的新用户的密码)是$2a$10$YI5SRl5OwiLS//AL.zGo/O6YxLWogcbIPkV54Zp9F7TXZ4Tk6JXRe@dur这是一个用户密码。我添加了相同的curl请求(使用失眠客户端生成)上面。Thank.Spring-boot 2实际上涉及重命名许多属性。您是否查看发行说明以确认您没有使用已重命名但尚未更新的属性?您是否使用Spring security 5?如果是这样,您可能必须迁移密码,并使用适当的编码器符号作为前缀,如图所示ed你解决问题了吗?我在使用Spring Boot 2的新应用程序时遇到了同样的问题。我正在使用新的密码格式,测试解码是否有效,但在尝试获取令牌时遇到了相同的错误。
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId></dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("clientapp")
.authorizedGrantTypes("password","refresh_token")
.authorities("USER")
.scopes("read", "write")
.resourceIds(RESOURCE_ID)
.secret(passwordEncoder.encode("SECRET"));
}
passwordEncoder.encode(rawPassword, hashedPassword)