调用 OAuth 2.0 服务
已注册的 OAuth 客户机可以调用 WebSphere® Application Server OAuth 服务授权端点来请求授权代码。已注册的 OAuth 客户机还可以调用 WebSphere Application Server OAuth 服务令牌端点来请求访问令牌。然后,客户机使用此访问令牌从 WebSphere Application Server 请求受保护的 Web 资源。
WebSphere Application Server OAuth 2.0 服务支持所有四个流。
授权代码流
调用授权端点以请求授权代码。
OAuth 客户机通过添加其客户机标识、客户机私钥、状态、重定向 URI 和可选作用域来将资源所有者或用户重定向到 WebSphere Application Server OAuth 2.0 授权服务。
https://<host_name>:<port_number>/oauth2/endpoint/<provider_name>/authorize
或 https://<host_name>:<port_number>/oauth2/declarativeEndpoint/<provider_name>/authorize
调用 OAuth 令牌端点以请求访问令牌。
OAuth 客户机通过添加 authorization_code 授权类型、authorization code、redirect_url 和 client_id 作为请求参数来实现从 WebSphere Application Server OAuth 2.0 令牌端点请求访问令牌。
https://<host_name>:<port_number>/oauth2/endpoint/<provider_name>/token
以下示例说明了使用授权代码时构造 URI 以及使用访问令牌来访问 Web 资源:
String charset = "UTF-8";
String param1 = "code";
if (isAuthorizationCode){
String query = String.format("response_type=%s&
client_id=%s&
client_secret=%s&
state=%s&
redirect_uri=%s&
scope=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(clientSecret, charset),
URLEncoder.encode(state, charset),
URLEncoder.encode(redirectURI, charset),
URLEncoder.encode(scope, charset));
String s = authorizationEndPoint + "?" + query;
System.out.println("Visit: " + s + "\nand grant permission");
System.out.print("Now enter the OAuth code you have received in redirect uri :");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String code = br.readLine();
param1 = "authorization_code";
query = String.format("grant_type=%s&
code=%s&
client_id=%s&
client_secret=%s&
state=%s&
redirect_uri=%s&
scope=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(code, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(clientSecret, charset),
URLEncoder.encode(state, charset),
URLEncoder.encode(redirectURI, charset),
URLEncoder.encode(scope, charset));
URL url = new URL(tokenEndPoint);
HttpsURLConnection con = (HttpsURLConnection)url. openConnection();
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
con.setDoOutput(true);
con.setRequestMethod("POST");
OutputStream output = null;
try {
output = con.getOutputStream();
output.write(query.getBytes(charset));
output.flush();
} finally {
if (output != null) try {
output.close();
} catch (IOException logOrIgnore) {}
}
con.connect();
System.out.println("response message is = " + con.getResponseMessage());
// read the output from the server
BufferedReader reader = null;
StringBuilder stringBuilder;
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
stringBuilder = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
} finally {
if (reader != null) try {
reader.close();
} catch (IOException logOrIgnore) {}
}
String tokenResponse = stringBuilder.toString();
System.out.println ("response is = " + tokenResponse);
JSONObject json = JSONObject.parse(tokenResponse);
if (json.containsKey("access_token")) {
accessToken = (String)json.get("access_token");
this.accessToken = accessToken;
}
if (json.containsKey("refresh_token")) {
refreshToken = (String)json.get("refresh_token");
}
//sendRequestForAccessToken(query);
if (accessToken != null) {
String query = String.format("access_token=%s",
URLEncoder.encode(accessToken, charset));
URL urlResource = new URL(resourceEndPoint);
HttpsURLConnection conn = (HttpsURLConnection) urlResource.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
conn.setDoOutput(true);
output = null;
try {
output = conn.getOutputStream();
output.write(query.getBytes(charset));
output.flush();
} finally {
if (output != null) try {
output.close();
} catch (IOException logOrIgnore) {}
}
conn.connect();
System.out.println("response to the resource request is = " + conn.getResponseMessage ());
reader = null;
if(conn.getResponseCode()>=200 && conn.getResponseCode() < 400) {
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
stringBuilder = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
} finally {
if (reader != null) try {
reader.close();
} catch (IOException logOrIgnore) {}
}
System.out.println ("response message to the request resource is = " + stringBuilder.toString());
} else {
isValidResponse = false;
}
}
}
隐式授权流
OAuth 客户机通过添加令牌 response_type、redirect_url、client_id、scope 和 state 作为请求参数来实现从 WebSphere Application Server OAuth 2.0 授权端点请求访问令牌。https://<host_name>:<port_number>/oauth2/endpoint/<provider_name>/authorize
或 https://<host_name>:<port_number>/oauth2/declarativeEndpoint/<provider_name>/authorize
以下示例说明了使用隐式授权时构造 URI:if (isImplicit) {
param1 = "token";
String query = String.format("response_type=%s&
client_id=%s&
state=%s&
redirect_uri=%s&
scope=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(state, charset),
URLEncoder.encode(redirectURI, charset),
URLEncoder.encode(scope, charset));
String s = authorizationEndPoint + "?" + query;
System.out.println("Visit: " + s + "\nand grant permission");
System.out.print("Now enter the access token you have received in redirect uri :");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
accessToken = br.readLine();
if (accessToken != null) {
// send Resource Request using the access token
}
}
客户机凭证流
OAuth 客户机使用客户机标识和私钥来访问令牌端点,并交换用于将来的资源请求的访问令牌。在此流中,客户机通过添加 client_credentials 授权类型、client_id 和 client_secret 作为请求参数来访问令牌端点。https://<host_name>:<port_number>/oauth2/endpoint/<provider_name>/token
以下示例说明了使用客户机凭证时构造 URI:if (isClientCredentials){
param1 = "client_credentials";
String query = String.format("grant_type=%s&
scope=%s&
client_id=%s&
client_secret=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(scope, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(clientSecret, charset));
accessToken = sendRequestForAccessToken(query);
if (accessToken != null) {
//send Resource Request using (accessToken);
}
}
资源所有者密码流
“资源所有者密码凭证”流将资源所有者的用户标识和密码直接传递给令牌端点。在此流中,OAuth 客户机通过添加 password 授权类型、client_id、client_secret、username、password、scope 和 state 作为请求参数来访问令牌端点。https://<host_name>:<port_number>/oauth2/endpoint/<provider_name>/token
以下示例说明了使用资源所有者密码时构造 URI:if (isResourceOwnerCredentials) {
param1 = "password";
String query = String.format("grant_type=%s&
username=%s&
password=%s&
scope=%s&
client_id=%s&
client_secret=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(resOwnerName, charset),
URLEncoder.encode(resOwnerPassword, charset),
URLEncoder.encode(scope, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(clientSecret, charset));
accessToken = sendRequestForAccessToken(query);
if (accessToken != null) {
//send Resource Request using (accessToken);
}
}
如果访问令牌已到期,那么可以发送刷新令牌以获取有效的访问令牌。以下示例说明了如何发送刷新令牌:if(isAccessToken) {
if (this.accessToken != null) {
if (!sendResourceRequest(this.accessToken)) {
// resource request failed...
//get refresh token
param1 = "refresh_token";
String query = String.format("grant_type=%s&
client_id=%s&
client_secret=%s&
refresh_token=%s&
scope=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(clientId, charset),
URLEncoder.encode(clientSecret, charset),
URLEncoder.encode(this.refreshToken, charset),
URLEncoder.encode(scope, charset));
accessToken = sendRequestForAccessToken(query);
if (accessToken != null) {
sendResourceRequest(accessToken);
}
}
}
}