【发布时间】:2022-12-21 12:22:36
【问题描述】:
我想用 Spring Authorization Server 项目构建一个授权服务器。现在我想使用 AuthorizationGrantType.PASSWORD。
我根据 Spring Authorization Server 项目的示例开发了一个演示项目。但是,当我尝试使用http://localhost:9000/oauth2/token?grant_type=password&username=user&password=pass(我在 Postman 中使用 client_id 和 client_secret 作为基本身份验证)请求,我得到 403。
我在这里缺少什么?
依赖关系:spring-boot-starter-web、spring-boot-starter-security、spring-security-oauth2-authorization-server(版本:0.2.2)
授权服务器配置类:
import java.security.*;
import java.security.interfaces.*;
import java.util.UUID;
import org.springframework.context.annotation.*;
import org.springframework.security.oauth2.core.*;
import org.springframework.security.oauth2.server.authorization.client.*;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("client1")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
@Bean
public ProviderSettings providerSettings() {
return ProviderSettings.builder()
.issuer("http://auth-server:9000")
.build();
}
@Bean
public JWKSource<SecurityContext> jwkSource() {
RSAKey rsaKey = generateRsa();
JWKSet jwkSet = new JWKSet(rsaKey);
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
}
private static RSAKey generateRsa() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
return new RSAKey.Builder(publicKey)
.privateKey(privateKey)
.keyID(UUID.randomUUID().toString())
.build();
}
private static KeyPair generateRsaKey() {
KeyPair keyPair;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
return keyPair;
}
}
默认安全配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.*;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity
public class DefaultSecurityConfig {
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeRequests(authorizeRequests ->
authorizeRequests
.anyRequest()
.authenticated()
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("pass")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(userDetails);
}
}
我在日志中发现了这条消息,可能与以下内容有关:
o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [POST /oauth2/token?grant_type=password&username=user&password=pass] with attributes [authenticated]
【问题讨论】:
-
很可能是 CORS,这是否回答了您的问题? How to configure CORS in a Spring Boot + Spring Security application?
-
@Toerktumlare 不。我禁用了 CORS,但得到了相同的响应。我也可以使用“../auth2/authorize”端点,所以它不应该与 CORS 相关。我还添加了一条日志消息来发布我发现它可能是相关的。
-
授予类型是密码,因此您需要使用用户名和密码进行身份验证。
-
client_id:clientId grant_type:password username:username password:password 作用域:read,write
标签: spring-security spring-security-oauth2