我用微服务架构实现了一个简单的系统,在我的系统中,大约有5个微服务实例,它们作为资源服务器工作。资源服务器和授权服务器之间的通信是通过遵循OAuth密码流的非对称方法来完成的。
当用户通过门户网站模块注册或登录系统以调用服务时,我必须返回一个包含电子邮件和access_token的响应,该响应应保存在本地存储中。
当我调用http://localhost:9098/oauth/token
端点时,出现以下错误。
org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException: Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it.
application.yml
security:
oauth2:
client:
grant-type: password
client-id: web
client-secret: 14292
access-token-uri: http://127.0.0.1:9098/oauth/token
配置类
@Configuration
public class WebPortalConfig {
@Bean
@ConfigurationProperties("security.oauth2.client")
public ClientCredentialsResourceDetails oAuthDetails()
{
return new ClientCredentialsResourceDetails();
}
@Bean
public RestTemplate restTemplate()
{
return new OAuth2RestTemplate(oAuthDetails());
}
}
OAuthDetails类
@Getter
@Setter
public class OAuthDetails {
private String access_token;
private String token_type;
private String refresh_token;
private int expires_in;
}
服务类别
private OAuthDetails getOAuthDetails()
{
String url="http://127.0.0.1:9098/oauth/token?grant_type=password&username=nafazbenzema@gmail.com&password=benz";
return restTemplate.getForObject(url, OAuthDetails.class);
}
第页。S-
如何克服这个错误?
这种方法正确与否,如果你有更好的方法,请建议作为答案
我在以前的代码中发现了另一种方法和一些错误。
错误01
为ClientCredentialsResourceDetails
创建了bean实例,但我使用的是password flow
。
我将发布我的答案以获得access_token
,并在OAUTH2
中使用password flow
进行响应。
application.yml
security:
oauth2:
access-token-uri: http://localhost:9098/oauth/token
client-id: web
client-secret: 14292
grant-type: password
属性类
@ConfigurationProperties(prefix = "security")
public class SecurityProperties {
private OAuth2Properies oauth2;
public OAuth2Properies getOauth2() {
return oauth2;
}
public void setOauth2(OAuth2Properies oauth2) {
this.oauth2 = oauth2;
}
public static class OAuth2Properies{
private String accessTokenUri;
private String clientId;
private String clientSecret;
private String grantType;
public String getAccessTokenUri() {
return accessTokenUri;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
}
}
customAuthenticationProvider类
@Component
@EnableConfigurationProperties(SecurityProperties.class)
public class Oauth2AuthenticationProvider {
private SecurityProperties securityProperties;
public Oauth2AuthenticationProvider(SecurityProperties securityProperties)
{
this.securityProperties=securityProperties;
}
public OAuth2AccessToken obtainToken(String username, String password) {
SecurityProperties.OAuth2Properies oAuthDetails=securityProperties.getOauth2();
ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
resourceDetails.setAccessTokenUri(oAuthDetails.getAccessTokenUri());
resourceDetails.setClientId(oAuthDetails.getClientId());
resourceDetails.setClientSecret(oAuthDetails.getClientSecret());
resourceDetails.setGrantType(oAuthDetails.getGrantType());
resourceDetails.setUsername(username);
resourceDetails.setPassword(password);
DefaultAccessTokenRequest defaultAccessTokenRequest = new DefaultAccessTokenRequest();
OAuth2AccessToken token;
try {
token = new ResourceOwnerPasswordAccessTokenProvider().obtainAccessToken(resourceDetails, defaultAccessTokenRequest);
} catch (OAuth2AccessDeniedException accessDeniedException) {
throw new BadCredentialsException("Invalid credentials", accessDeniedException);
}
return token;
}
}
服务类别
@Service
public class UserServiceImpl{
private String getAccessToken(String userName,String password)
{
authenticationProvider.obtainToken(username,password).toString();
}
}