在尝试创建使用OAuth 2.0授权代码授权流程的示例客户端时,我一直在努力。
我能够成功使用客户端凭据流但是当我尝试使用授权代码流时,我不会被重定向到正确的uri。
调用OAuth2RestTmplate.exchange方法时,我在RestTemplate.doExecute(...)方法中得到一个重定向异常。它是从finally子句抛出的。 响应为空,但if不会停止响应。
finally {
if (response != null) {
response.close();
}
我仍然会收到提示登录和授权的提示,但不会将其定向到包含数据的响应。我只是被重定向回客户端主页。 Postman使用具有相同客户端凭据的授权代码流的相同调用是成功的,因此我知道客户端注册是正确的。
我可以用另一双眼睛看看我失踪了什么。提前致谢!以下是我的代码摘录。
使用oauth2客户端凭据流工作客户端
客户端应用:
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
public class ClientExampleClientCredentials extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ClientExampleClientCredentials.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ClientExampleClientCredentials.class);
}
}
控制器:
@RestController
public class HomeController {
@Value("${security.oauth2.client.clientId}")
private String clientId;
@Value("${security.oauth2.client.clientSecret}")
private String clientSecret;
@Value("${security.oauth2.client.apiUrl}")
private String apiUrl;
@Value("${security.oauth2.client.scope}")
private List<String> scopes;
@Value("${security.oauth2.client.accessTokenUri}")
private String accessTokenUri;
/**
* Example of using the OAuth2RestTemplate to access external resources
*
* The OAuth2RestTemplate takes care of exchanging credentials with the auth server, as well as adding the
* bearer token to each request to the FHIR services.
*
*/
@RequestMapping("/ex-1")
public String retrievePatientByIdUsingRestTemplate(@RequestParam String id) {
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(getClientCredentialsResourceDetails(), new DefaultOAuth2ClientContext());
ResponseEntity<String> response = oAuth2RestTemplate.exchange(apiUrl + "/Patient/" + id, HttpMethod.GET, null, String.class);
String responseBody = response.getBody();
return responseBody;
}
private ClientCredentialsResourceDetails getClientCredentialsResourceDetails() {
ClientCredentialsResourceDetails clientCredentialsResourceDetails = new ClientCredentialsResourceDetails();
clientCredentialsResourceDetails.setAccessTokenUri(accessTokenUri);
clientCredentialsResourceDetails.setAuthenticationScheme(AuthenticationScheme.header);
clientCredentialsResourceDetails.setClientId(clientId);
clientCredentialsResourceDetails.setClientSecret(clientSecret);
clientCredentialsResourceDetails.setScope(scopes);
return clientCredentialsResourceDetails;
}
}
application.yml
security:
oauth2:
client:
clientId: client_id
clientSecret: secret
apiUrl: http://localhost:8080/testData/data
accessTokenUri: http://localhost:8080/test-auth/token
scope: system/*.read
这可以很好地验证我,然后重定向到我的服务网址。但是,授权代码流程不起作用。
使用oauth2授权代码流破坏客户端
客户端应用
@SpringBootApplication (exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
public class ClientExampleAccessToken extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ClientExampleAccessToken.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ClientExampleAccessToken.class);
}
}
控制器:
package org.ihc.clinical.controller;
@Configuration
@EnableOAuth2Client
@RestController
public class HomeController {
@Value("${security.oauth2.client.clientId}")
private String clientId;
@Value("${security.oauth2.client.clientSecret}")
private String clientSecret;
@Value("${security.oauth2.client.accessTokenUri}")
private String accessTokenUri;
@Value(("${security.oauth2.client.userAuthorizationUri}"))
private String userAuthorizationUri;
@Value("${security.oauth2.client.apiUrl}")
private String apiUrl;
@Value("${security.oauth2.client.redirectUri}")
private String redirectUri;
@RequestMapping("/ex-1")
public String retrievePatientByIdUsingRestTemplate(@RequestParam String empi) {
OAuth2ProtectedResourceDetails resource = resource();
String path = apiUrl + "/Patient/" + empi;
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resource, new DefaultOAuth2ClientContext());
***/*error occurs here in RestTemplate.doExcute. error:org.springframework.security.oauth2.client.resource.UserRedirectRequiredException:
A redirect is required to get the users approval */***
ResponseEntity<String> response = oAuth2RestTemplate.exchange(path, HttpMethod.GET, null, String.class);
//AuthorizationCodeAccessTokenProvider provider = new //AuthorizationCodeAccessTokenProvider();
//Token Request
//AccessTokenRequest request = new DefaultAccessTokenRequest();
//String code = provider.obtainAuthorizationCode(resource, request);
//request.setAuthorizationCode(code);
//OAuth2AccessToken oAuth2AccessToken = //provider.obtainAccessToken(resource, request);
//Token Response
//String tokenValue = oAuth2AccessToken.getValue();
//return tokenValue;
}
//Call when ready to send token Request
private OAuth2ProtectedResourceDetails resource() {
AuthorizationCodeResourceDetails authorizationCodeResourceDetails = new AuthorizationCodeResourceDetails();
authorizationCodeResourceDetails.setClientId(clientId);
authorizationCodeResourceDetails.setClientSecret(clientSecret);
authorizationCodeResourceDetails.setAccessTokenUri(accessTokenUri);
authorizationCodeResourceDetails.setUserAuthorizationUri(userAuthorizationUri);
//authorizationCodeResourceDetails.setScope(scopes);
authorizationCodeResourceDetails.setPreEstablishedRedirectUri(redirectUri);
return authorizationCodeResourceDetails;
}
}
application.yml
security:
oauth2:
client:
clientId: clientid
clientSecret: secret
accessTokenUri: http://localhost:8080/test-auth/token
userAuthorizationUri: http://localhost:8080/test-auth/authorize
apiUrl: http://localhost:8080/test-fhir-cdr/data
redirectUri: http://localhost:8080/test-examples-access-token
答案 0 :(得分:1)
我终于在这里找到了解决方案:https://projects.spring.io/spring-security-oauth/docs/oauth2.html
我需要将以下代码添加到控制器:
@Autowired
private OAuth2ClientContext oauth2Context;
@Bean
public OAuth2RestTemplate getOauth2RestTemplate() {
return new OAuth2RestTemplate(resource(), oauth2Context);
}
然后调用getOauth2RestTemplate(),如下所示:
@RequestMapping("/ex-1")
public String retrievePatientByIdUsingRestTemplate(@RequestParam String empi) {
String path = apiUrl + "/Patient/" + empi;
OAuth2RestTemplate oAuth2RestTemplate = getOauth2RestTemplate();
ResponseEntity<String> response = oAuth2RestTemplate.exchange(path, HttpMethod.GET, null, String.class);
return response.getBody();
}