我假设您的授权/资源服务器是外部应用程序。您可以使用您的第一个应用程序成功登录,因此流程正常。您有两个客户端应用程序具有自己的 client_id、client_secret 等参数。如果这些参数不同,那么授权/资源服务器将为第一个和第二个客户端应用程序返回不同的 bareer token 和 sessionid cookie。否则您需要在授权/资源服务器中对它们进行授权。
我会在用户登录第一个应用程序时提供,然后在后台你也登录第二个应用程序。
为了自动授权第二个应用程序,您可以尝试在第一次应用程序登录成功后使用自己的参数手动为第二个应用程序执行 oauth2 登录流程,并将 cookie 发送到您从 oauth2 登录获得的前端。
对于手动 oauth2 登录,您可以尝试以下代码:
private Cookie oauth2Login(String username, String password, String clientId, String clientSecret) {
try {
String oauthHost = InetAddress.getByName(OAUTH_HOST).getHostAddress();
HttpHeaders headers = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
// Basic Auth
String plainCreds = clientId + ":" + clientSecret;
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = org.apache.commons.net.util.Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
headers.add("Authorization", "Basic " + base64Creds);
// form param
map.add("username", username);
map.add("password", password);
map.add("grant_type", GRANT_TYPE);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map,
headers);
// CALLING TOKEN URL
OauthTokenRespone res = null;
try {
res = restTemplate.postForObject(OAUTH_HOST, request,
OauthTokenRespone.class);
} catch (Exception ex) {
ex.printStackTrace();
}
Optional<OauthTokenRespone> optRes = Optional.ofNullable(res);
String accessToken = optRes.orElseGet(() -> new OauthTokenRespone("", "", "", "", "", ""))
.getAccess_token();
// CALLING RESOURCE
headers.clear();
map.clear();
headers.setContentType(MediaType.APPLICATION_JSON);
map.add("access_token", accessToken);
request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
Cookie oauthCookie = null;
if (accessToken.length() > 0) {
HttpEntity<String> response = restTemplate.exchange(
OAUTH_RESOURCE_URL.replace(OAUTH_HOST, oauthHost) + "?access_token=" + accessToken,
HttpMethod.POST, request, String.class);
String cookie = Optional.ofNullable(response.getHeaders().get("Set-Cookie"))
.orElseGet(() -> Arrays.asList(new String(""))).get(0);
if (cookie.length() > 0) {
String[] c = cookie.split(";")[0].split("=");
oauthCookie = new Cookie(c[0], c[1]);
oauthCookie.setHttpOnly(true);
}
}
return Optional.ofNullable(oauthCookie).orElseGet(() -> new Cookie("Ops", ""));
} catch (Throwable t) {
return new Cookie("Ops", "");
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class OauthTokenRespone {
private String access_token;
private String token_type;
private String refresh_token;
private String expires_in;
private String scope;
private String organization;
// getter and setter
}
并在首次应用登录后调用此方法,如下所示:
Cookie oauthCookie = oauth2Login(authenticationRequest.getUsername(), authenticationRequest.getPassword(),
CLIENT_ID, CLIENT_SECRET);
获取 cookie 后,您需要更改其名称(例如 JSESSIONID-SECOND),因为相同的 cookie 会相互覆盖,并且还需要将其域路径更改为第二个应用程序域。
response.addCookie(oauthCookie);
最后你需要在响应中添加 cookie(它是 HttpServletResponse 参考)。
希望对你有帮助!