带有 client_credentials 的 Spring Oauth2 不验证用户
Posted
技术标签:
【中文标题】带有 client_credentials 的 Spring Oauth2 不验证用户【英文标题】:Spring Oauth2 with client_credentials does not validate user 【发布时间】:2021-11-11 01:03:08 【问题描述】:我正在尝试使用 Spring Boot 设置一个简单的 Oauth2 服务器,目前只有 client_credentials 流,在内存中使用用户和客户端等。基本上是最基本的项目,所以我可以在它上面进行构建。有一段时间没有在 Spring 中使用 Oauth2,所以我有点卡住了。我可以获得访问令牌,但似乎 Spring 实际上并没有验证客户端发送的用户名/密码。下面是两个配置类(AuthorizationServerConfigurerAdapter、WebSecurityConfigurerAdapter):
@Configuration
@EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter
private final AuthenticationManager authenticationManager;
private final PasswordEncoder passwordEncoder;
private final UserDetailsService userService;
@Value("$jwt.signing-key")
private String jwtSigningKey;
@Value("$jwt.accessTokenValidititySeconds")
private int accessTokenValiditySeconds;
@Value("$jwt.refreshTokenValiditySeconds")
private int refreshTokenValiditySeconds;
public OAuthConfiguration(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder, UserDetailsService userService)
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userService = userService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
clients.inMemory()
.withClient("test-client-id")
.secret(passwordEncoder.encode("test-client-secret"))
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.authorizedGrantTypes("client_credentials")
.scopes("read", "write")
.resourceIds("api");
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints)
endpoints
.accessTokenConverter(accessTokenConverter())
.userDetailsService(userService)
.authenticationManager(authenticationManager);
@Bean
JwtAccessTokenConverter accessTokenConverter()
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(jwtSigningKey);
return converter;
和:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
public WebSecurityConfiguration(CustomAuthenticationEntryPoint customAuthenticationEntryPoint)
this.customAuthenticationEntryPoint = customAuthenticationEntryPoint;
@Bean
public DaoAuthenticationProvider authenticationProvider(UserDetailsService userDetailsService)
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService);
return provider;
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception
return super.userDetailsServiceBean();
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.inMemoryAuthentication()
.withUser("user1")
.password("$2a$10$sWszOXuTlN0amQi8vXp4cerb.tJUQo.4FzLAnTCsSqChsYhlLdQWW")
.roles("USER");
@Override
protected void configure(HttpSecurity http) throws Exception
http
.cors().disable().csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and().exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint).accessDeniedHandler(new CustomAccessDeniedHandler());
所以我可以使用任何用户名/密码调用“/oauth/token”端点,从而获得访问令牌。但是,正在验证客户端 ID 和客户端密码。
感谢任何帮助
【问题讨论】:
如果您从 spring 开始使用 oauth 服务器,那么它们是 not going to implement 密码流(资源所有者),因为它似乎在 oauth 2.1 specs 中已被弃用。 【参考方案1】:这是 grant_type client_credentials
的默认行为。因此,您无需使用此 grant_type 将 username
和 password
传递给令牌端点。在此流程中,AuthorizationServer
将仅验证客户端 ID 和客户端密码。
POST /token
Host: authorization-server.com
grant_type=client_credentials
&client_id=xxxxxxxxxx
&client_secret=xxxxxxxxxx
【讨论】:
谢谢!那么 Spring 是否有一些用于令牌授予和验证用户的默认实现,或者如果我也想验证用户是否需要实现自己的(扩展 ClientCredentialsTokenGranter?)以上是关于带有 client_credentials 的 Spring Oauth2 不验证用户的主要内容,如果未能解决你的问题,请参考以下文章
OneLogin是否支持client_credentials?
spring security client_credentials grant_type - 支持刷新令牌
如何使用 client_credentials 从资源服务器访问另一个 oauth2 资源?
是否支持 Spring Boot WebClient OAuth2 client_credentials?