使用 Spring oauth2 使用 OAuth 保护的 REST 网络服务
Consume an OAuth-secured REST webservice using Spring oauth2
我想从使用 oauth2 保护其资源的服务器使用 REST 网络服务。
我使用Spring引导(JHipster)。
要做到这一点,我在 SecurityConfiguration
class 这个 :
@Value("${oauth.resource:http://sercverUsingOAuth2}")
private String baseUrl;
@Value("${oauth.authorize:http://sercverUsingOAuth2/rest/oauth/token}")
private String authorizeUrl;
@Value("${oauth.token:http://sercverUsingOAuth2/rest/oauth/token}")
private String tokenUrl;
@Bean
public OAuth2RestOperations oauth2RestTemplate() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(resource(),
new DefaultOAuth2ClientContext(atr));
}
@Bean
protected OAuth2ProtectedResourceDetails resource() {
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setAccessTokenUri(tokenUrl);
resource.setUserAuthorizationUri(authorizeUrl);
resource.setClientId("client_id");
resource.setClientSecret("client_secret");
resource.setGrantType("grant_type");
return resource;
}
此 class (SecurityConfiguration
) 使用注释:
@Configuration
@EnableWebSecurity
@EnableOAuth2Client
这是我的 controller
(Spring MVC):
@RestController
@RequestMapping("/consume")
public class MyContrtoller {
@Inject
private OAuth2RestOperations oauth2RestTemplate;
@RequestMapping(value = "/oauth2", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<DataModel> getProducts() {
ResponseEntity<MyModel> forEntity = oauth2RestTemplate
.getForEntity("http://sercverUsingOAuth2/rest/resourceToConsume",
MyModel.class);
return forEntity.getBody().getData();
}
}
然而,当我想使用我的网络服务 (http://myHost/consume/oauth2) 时,我得到了这个异常:
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.
我用谷歌搜索并找到了这个:
但这对我没有帮助。
谢谢。
您对授权 url 和令牌 url 使用相同的 URL。那是我的第一条线索,然后我看到了你的评论。
即使您正在更改授权类型,您仍在使用 "AuthorizationCodeResourceDetails",而您应该使用 "ClientCredentialsResourceDetails"。这种类型的 ResourceDetails 旨在用于您正在解释的案例。
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri(TOKEN_URL);
resource.setClientId(CLIENT_ID);
resource.setClientSecret(CLIENT_SECRET);
resource.setClientAuthenticationScheme(AuthenticationScheme.form); //This line isn't always needed
return resource;
我想从使用 oauth2 保护其资源的服务器使用 REST 网络服务。
我使用Spring引导(JHipster)。
要做到这一点,我在 SecurityConfiguration
class 这个 :
@Value("${oauth.resource:http://sercverUsingOAuth2}")
private String baseUrl;
@Value("${oauth.authorize:http://sercverUsingOAuth2/rest/oauth/token}")
private String authorizeUrl;
@Value("${oauth.token:http://sercverUsingOAuth2/rest/oauth/token}")
private String tokenUrl;
@Bean
public OAuth2RestOperations oauth2RestTemplate() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(resource(),
new DefaultOAuth2ClientContext(atr));
}
@Bean
protected OAuth2ProtectedResourceDetails resource() {
AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
resource.setAccessTokenUri(tokenUrl);
resource.setUserAuthorizationUri(authorizeUrl);
resource.setClientId("client_id");
resource.setClientSecret("client_secret");
resource.setGrantType("grant_type");
return resource;
}
此 class (SecurityConfiguration
) 使用注释:
@Configuration
@EnableWebSecurity
@EnableOAuth2Client
这是我的 controller
(Spring MVC):
@RestController
@RequestMapping("/consume")
public class MyContrtoller {
@Inject
private OAuth2RestOperations oauth2RestTemplate;
@RequestMapping(value = "/oauth2", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<DataModel> getProducts() {
ResponseEntity<MyModel> forEntity = oauth2RestTemplate
.getForEntity("http://sercverUsingOAuth2/rest/resourceToConsume",
MyModel.class);
return forEntity.getBody().getData();
}
}
然而,当我想使用我的网络服务 (http://myHost/consume/oauth2) 时,我得到了这个异常:
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.
我用谷歌搜索并找到了这个:
但这对我没有帮助。
谢谢。
您对授权 url 和令牌 url 使用相同的 URL。那是我的第一条线索,然后我看到了你的评论。
即使您正在更改授权类型,您仍在使用 "AuthorizationCodeResourceDetails",而您应该使用 "ClientCredentialsResourceDetails"。这种类型的 ResourceDetails 旨在用于您正在解释的案例。
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri(TOKEN_URL);
resource.setClientId(CLIENT_ID);
resource.setClientSecret(CLIENT_SECRET);
resource.setClientAuthenticationScheme(AuthenticationScheme.form); //This line isn't always needed
return resource;