gpt4 book ai didi

oauth-2.0 - 找不到 Spring Boot OAuth 2.0 UserDetails 用户

转载 作者:行者123 更新时间:2023-12-04 13:13:30 27 4
gpt4 key购买 nike

我是 Spring Boot 的新手,我正在尝试配置 OAuth 2.0。我此时遇到的问题是,当我尝试请求访问 token 时,我不断收到以下消息:

{ "error": "invalid_grant", "error_description": "Bad credentials" }



Spring Boot 控制台中的错误消息说找不到用户。

: 使用 org.springframework.security.authentication.dao.DaoAuthenticationProvider 的身份验证尝试
: 未找到用户“stromero”
: 返回单例 bean 'authenticationAuditListener' 的缓存实例

我已经使用 JPA 实现了一个已经保存到数据库的自定义用户,我无法弄清楚为什么 Spring Security 找不到这个用户,这可能是我的逻辑或配置的问题。如果有更多经验的人可以查看我的代码并指导我走向正确的方向,那将不胜感激。

这是 HTTP 请求:

POST /oauth/token HTTP/1.1 Host: localhost:8181 Authorization: Basic YnJvd3NlcjpzZWNyZXQ= Cache-Control: no-cache Content-Type: application/x-www-form-urlencoded username=stromero&password=password&client_id=browser&client_secret=secret&grant_type=password



这些是我用来实现自定义用户和 OAuth 2.0 的类
@Repository
public interface UserRepository extends CrudRepository<CustomUser, String> {

public CustomUser findByUsername(String name);
}

下面是我创建的自定义用户
@Entity
@Table (name = "custom_user")
public class CustomUser {

@Id
@Column(name = "id", nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "username", unique=true, nullable = false)
private String username;
@Column(name = "password", nullable = false)
private String password;
@ElementCollection
private List<String> roles = new ArrayList<>();

public List<String> getRoles() {
return roles;
}

public void setRoles(List<String> roles) {
this.roles = roles;
}

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;
}
}

下面是一个 customdetails 服务,它从数据库中读取用户信息并将其作为 UserDetails 对象返回
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

CustomUser customUser = userRepository.findByUsername(s);

boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;

return new User(
customUser .getUsername(),
customUser .getPassword().toLowerCase(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(customUser.getRoles()));
}
public Collection<? extends GrantedAuthority> getAuthorities(List<String> roles) {
List<GrantedAuthority> authList = getGrantedAuthorities(roles);
return authList;
}


public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}

下面的类是一个包含 UserDetailsS​​ervice 和 ClientDetailsS​​ervice 的数据结构
public class ClientAndUserDetailsService implements UserDetailsService,
ClientDetailsService {

private final ClientDetailsService clients;

private final UserDetailsService users;

private final ClientDetailsUserDetailsService clientDetailsWrapper;

public ClientAndUserDetailsService(ClientDetailsService clients,
UserDetailsService users) {
super();
this.clients = clients;
this.users = users;
clientDetailsWrapper = new ClientDetailsUserDetailsService(this.clients);
}

@Override
public ClientDetails loadClientByClientId(String clientId)
throws ClientRegistrationException {
return clients.loadClientByClientId(clientId);
}

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {

UserDetails user = null;
try{
user = users.loadUserByUsername(username);
}catch(UsernameNotFoundException e){
user = clientDetailsWrapper.loadUserByUsername(username);
}
return user;
}
}

下面的类是我使用 Spring Boot 对 OAuth 2.0 的配置
 @Configuration
public class OAuth2SecurityConfiguration {

@Configuration
@EnableWebSecurity
protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Autowired
protected void registerAuthentication(
final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}


@Configuration
@EnableResourceServer
protected static class ResourceServer extends
ResourceServerConfigurerAdapter {

@Override
public void configure(HttpSecurity http) throws Exception {

http.csrf().disable();

http.authorizeRequests().antMatchers("/oauth/token").anonymous();

// Require all GET requests to have client "read" scope
http.authorizeRequests().antMatchers(HttpMethod.GET, "/**")
.access("#oauth2.hasScope('read')");

// Require all POST requests to have client "write" scope
http.authorizeRequests().antMatchers(HttpMethod.POST,"/**")
.access("#oauth2.hasScope('write')");
}

}

@Configuration
@EnableAuthorizationServer
@Order(Ordered.LOWEST_PRECEDENCE - 100)
protected static class AuthorizationServer extends
AuthorizationServerConfigurerAdapter {

@Autowired
private AuthenticationManager authenticationManager;

private ClientAndUserDetailsService combinedService;

public AuthorizationServer() throws Exception {

ClientDetailsService clientDetailsService = new InMemoryClientDetailsServiceBuilder()
.withClient("browser")
.secret("secret")
.authorizedGrantTypes("password")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read","write")
.resourceIds("message")
.accessTokenValiditySeconds(7200)
.and()
.build();

// Create a series of hard-coded users.
UserDetailsService userDetailsService = new CustomUserDetailsService();
combinedService = new ClientAndUserDetailsService(clientDetailsService, userDetailsService);
}

@Bean
public ClientDetailsService clientDetailsService() throws Exception {
return combinedService;
}
@Bean
public UserDetailsService userDetailsService() {
return combinedService;
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authenticationManager(authenticationManager);
}

@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.withClientDetails(clientDetailsService());
}

}

}

下面是我的 pom.xml 文件
    <properties>
<tomcat.version>8.0.8</tomcat.version>
</properties>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

<!-- Postgres JDBC Driver -->

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.2-1002-jdbc4</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Hibernate validator -->

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>


<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>17.0</version>
</dependency>

</dependencies>

最佳答案

是的,我有同样的问题...想使用 JPA 的 UserDetailsService但同样的问题 - 找不到用户......最终得到解决,这要归功于 GitHub 上 Dave Syer 的 OAuth2 示例。

问题似乎出在 @EnableAuthorizationServer AuthorizationServer 中 Autowiring 的 authenticationManager 实例中类(class)。 AuthenticationManager 在那里 Autowiring 并且似乎使用默认值初始化 DAOAuthenticationProvider ,并且由于某种原因它不使用自定义 JPA UserDetailsService我们在 WebSecurityConfiguration 中初始化 authenticationManager .

在 Dave Syer 示例中,authenticationManager 在 WebSecurityConfiguration 中作为 bean 公开:

    @Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

然后在 AuthorizationServer我们 Autowiring authenticationManager 如下:
    @Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;

完成后,我终于设法根据我的客户 JPA 用户存储库对我的用户进行了身份验证。

关于oauth-2.0 - 找不到 Spring Boot OAuth 2.0 UserDetails 用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26208087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com