我正在尝试以编程方式从我的OAuth授权服务器检索OAuth访问令牌。我可以使用以下步骤检索令牌:
直接浏览器访问http://localhost:8080/oauth/authorize?client_id=clientId&response_type=code&redirect_uri=http://localhost:10000/client/landing,此端点需要身份验证才能访问,因此浏览器被重定向到登录表单,在其中输入由我编写的自定义用户详细信息服务验证的用户名和密码
浏览器现在位于一个页面上,该页面可以验证我要授予客户端访问我受保护资源的范围。我进行选择,然后点击授权按钮。
浏览器重定向到提供的重定向uri,并将授权代码作为查询参数。 (例如http://localhost:10000/client/landing?code=J23Dxx)
然后我获取code参数,并将其用于POST(在邮递员中)到/ oauth / token端点。 (例如localhost:8080 / oauth / token?grant_type = authorization_code&username = clientId&password = clientSecret&code = J23Dxx&redirect_uri = http:// localhost:10000 / client / landing)
这将返回访问令牌,一切正常。
当尝试从我的客户端应用程序使用OAuth2RestTemplate访问令牌时,会出现问题。这是我的客户端配置类:
@Configuration
@EnableOAuth2Client
public class ClientConfig {
@Value("${app.clientId}")
private String clientId;
@Value("${app.clientSecret}")
private String clientSecret;
@Value("${app.resourceId}")
private String resourceId;
@Value("${app.clientAuthUri}")
private String clientAuthUri;
@Value("${app.tokenUri}")
private String tokenUri;
@Value("${app.directUri}")
private String redirectUri;
@Bean
public OAuth2ProtectedResourceDetails getResourceDetails() {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
details.setId(resourceId);
details.setClientId(clientId);
details.setClientSecret(clientSecret);
details.setScope(Arrays.asList("read", "write"));
details.setUserAuthorizationUri(clientAuthUri);
details.setAccessTokenUri(tokenUri);
details.setPreEstablishedRedirectUri(redirectUri);
details.setUseCurrentUri(false);
return details;
}
@Autowired
private OAuth2ClientContext oAuth2ClientContext;
@Bean
public OAuth2RestOperations oAuthTemplate(OAuth2ClientContext clientContext) {
OAuth2RestTemplate template = new OAuth2RestTemplate(getResourceDetails(), oAuth2ClientContext);
return template;
}
}
然后,我尝试使用OAuth rest模板获取访问令牌:
@Service
public class OAuthService {
@Autowired
private OAuth2RestOperations oauthTemplate;
public OAuth2AccessToken getToken() {
return oauthTemplate.getAccessToken();
}
}
运行getToken()方法会导致InsufficientAuthenticationException,这很有意义,因为我没有输入用户名和密码来访问oauth / authorize端点。但是由于我使用的是授权码流程,因此不能在资源详细信息上设置用户名和密码。我尝试以相同的方式进入oauth / authorize端点后获取令牌,但是在那种情况下,我收到关于可能的CSRF攻击的错误,我认为这是由于授权服务器期望令牌请求上的状态参数。由于oauth / authorize端点是由浏览器命中的,而令牌端点是由OAuth2RestTemplate命中的,因此授权中不会保留任何状态。
我如何利用OAuth2RestTemplate访问令牌,或者我的设计存在其他一些根本性的问题在阻止它工作?
令我惊讶的是,我没有找到更多有关此的信息。我认为建议对授权和令牌端点进行身份验证是错误的做法吗?如果在需要考虑资源详细信息之前需要进行身份验证的情况下,使用OAuth2RestTemplate的标准方法是什么?