- OAuth2.0介紹
OAuth 2 是一個授權框架,或稱授權標準,它可以使第三方應用程序或客戶端獲得對HTTP服務上(例如 Google,GitHub )用戶帳戶信息的有限訪問權限。OAuth 2 通過將用戶身份驗證委派給託管用戶帳戶的服務以及授權客戶端訪問用戶帳戶進行工作。綜上,OAuth 2 可以爲 Web 應用 和桌面應用以及移動應用提供授權流程。
注:使用OAuth2 認證的好處就是你只需要一個賬號密碼,就能在各個網站進行訪問,而免去了在每個網站都進行註冊的繁瑣過程
- OAuth2.0 授權
授權碼模式是功能最完整、流程最嚴密的授權模式,它的特點是通過客戶端的後臺服務器,與“服務器提供”的認證服務器進行互動
代碼實現
package com.smartdot.grcsp.common.servlet;
import com.smartdot.commons.util.PropertyGetter;
import net.sf.json.JSONObject;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
/**
* @author xxx
* @date 2019/09/10
* @description 單點登錄OAuth2.0操作類
* 步驟:
* 1.門戶系統獲取臨時授權碼
* 2.通過授權碼獲取token令牌
* 3.通過令牌獲取用戶信息
*/
public class LoginUtil {
private static Logger logger = Logger.getLogger(LoginInterceptor.class);
//測試
private final static String CLIENT_SECRET= PropertyGetter.getString("client_secret");
private final static String CLIENT_ID=PropertyGetter.getString("client_id");
private final static String PORTAL_URL = PropertyGetter.getString("portal_url");
//生產
private final static String PRO_CLIENT_SECRET= PropertyGetter.getString("pro_client_secret");
private final static String PRO_CLIENT_ID=PropertyGetter.getString("pro_client_id");
private final static String PRO_PORTAL_URL = PropertyGetter.getString("pro_portal_url");
/**
* @param grant_type表示使用的授權模式,必選,此處固定值爲“authorization_code
* @param code表示上一步獲得的授權嗎,必選
* @param client_id 表示客戶端ID,必選
* @param client_secret表示客戶端密鑰,必選
* @method post
* @return idpEntity
* @Description: 獲取Token
*/
public static JSONObject getToken(String portalUrl,String code,String clientId,String clientSecret) {
String url = portalUrl + "/o/oauth2/token";
System.out.println("url============" + url);
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout('썐');
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
NameValuePair[] pairs = new NameValuePair[]{new NameValuePair("client_id", clientId), new NameValuePair("client_secret", clientSecret), new NameValuePair("grant_type", "authorization_code"), new NameValuePair("code", code)};
postMethod.setRequestBody(pairs);
int status = 0;
try {
System.out.println("查詢token=============");
status = client.executeMethod(postMethod);
System.out.println("查詢token結束=============");
} catch (IOException var14) {
var14.printStackTrace();
}
System.out.println("status:="+status);
String result;
if(status == 200) {
result = null;
String var9 = "";
try {
result = postMethod.getResponseBodyAsString();
logger.debug("result======" + result);
InputStream inputStream = postMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();
String str = "";
while((str = br.readLine()) != null) {
stringBuffer.append(str);
}
var9 = stringBuffer.toString();
return JSONObject.fromObject(var9);
} catch (IOException var15) {
var15.printStackTrace();
}
}
return null;
}
/**
* @param portalUrl 門戶系統域名
* @param code 臨時授權碼
* @param clientId
* @param clientSecret
* @return
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws KeyManagementException
* @description 生產環境獲取token
*/
public static JSONObject getRroToken(String portalUrl,String code,String clientId,String clientSecret) throws KeyStoreException, NoSuchAlgorithmException, IOException, KeyManagementException {
String url = portalUrl + "/o/oauth2/token";
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
String parma = "client_id="+clientId+"&client_secret="+clientSecret+"&code="+code+"&grant_type=authorization_code";
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
System.out.println("parma========"+parma);
StringEntity postingString = new StringEntity(parma,"utf-8");
httpPost.setEntity(postingString);
CloseableHttpResponse response = httpclient.execute(httpPost);
try {
if(response!=null){
System.out.println("status============="+response.getStatusLine());
HttpEntity entity = response.getEntity();
if(entity==null){
System.out.println("entity==="+entity);
return null;
}
return JSONObject.fromObject(EntityUtils.toString(entity));
}
} finally {
response.close();
}
return null;
}
/**
* @param token 表示上一步獲得的訪問令牌
* @param token_type 表示令牌類型。該值大小寫不敏感,必選項,可以是bearer類型或mac類型
* @method post
* @return idpEntity
* @Description: 獲取用戶信息
*/
public static JSONObject getUseInfo(String portalUrl, String tokenType, String accessToken) {
logger.info("portalUrl======" + portalUrl + "tokenType=" + tokenType + "accessToken=" + accessToken);
String url = portalUrl + "/api/jsonws/user/get-current-user";
logger.info("url==" + url);
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
GetMethod getMethod = new GetMethod(url);
getMethod.setRequestHeader("Content-Type", "application/json");
getMethod.setRequestHeader("Authorization","Bearer "+accessToken);
int status = 0;
try {
status = client.executeMethod(getMethod);
} catch (IOException var14) {
logger.debug(var14);
}
System.out.println("status:="+status);
String result;
if(status == 200) {
String var9 = "";
try {
result = getMethod.getResponseBodyAsString();
logger.debug("result======" + result);
InputStream inputStream = getMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer stringBuffer = new StringBuffer();
String str = "";
while((str = br.readLine()) != null) {
stringBuffer.append(str);
}
var9 = stringBuffer.toString();
return JSONObject.fromObject(var9);
} catch (IOException var15) {
logger.debug(var15);
}
}
return null;
}
/**
* @param portalUrl
* @param tokenType
* @param accessToken
* @return
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws IOException
* @throws KeyManagementException
* @description 生產環境獲取用戶信息
*/
public static JSONObject getProUseInfo(String portalUrl, String tokenType, String accessToken) throws KeyStoreException, NoSuchAlgorithmException, IOException, KeyManagementException{
logger.info("portalUrl======" + portalUrl + "tokenType=" + tokenType + "accessToken=" + accessToken);
String url = portalUrl + "/api/jsonws/user/get-current-user";
logger.info("url==" + url);
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpGet.setHeader("Authorization","Bearer "+accessToken);
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
if(response!=null){
System.out.println("status============="+response.getStatusLine());
HttpEntity entity = response.getEntity();
if(entity==null){
System.out.println("entity==="+entity);
return null;
}
return JSONObject.fromObject(EntityUtils.toString(entity));
}
} finally {
response.close();
}
return null;
}
//登錄調用
public static JSONObject getLogin(HttpServletRequest request, HttpServletResponse response) {
String portalUrl = "";
String clientId = "";
String clientSecret = "";
Boolean mark = false;
if("生產環境應用域名".equalsIgnoreCase(request.getServerName())){
portalUrl = PRO_PORTAL_URL;
clientId = PRO_CLIENT_ID;
clientSecret = PRO_CLIENT_SECRET;
System.out.println("生產環境");
System.out.println("portalUrl==="+portalUrl);
System.out.println("clientId==="+clientId);
System.out.println("clientSecret==="+clientSecret);
mark = true;
}else if("測試環境應用域名".equalsIgnoreCase(request.getServerName())){
portalUrl = PORTAL_URL;
clientId = CLIENT_ID;
clientSecret = CLIENT_SECRET;
System.out.println("測試環境");
}else{
System.out.println("========非測試或者正式環境無法調用單點登錄=======");
return null;
}
try {
//獲取臨時授權碼
String code = request.getParameter("code");
System.out.println("--------------------------------------------code is:" + code);
//token類型
String accessToken;
//token令牌
String tokenType;
JSONObject obj = null;
if(org.apache.commons.lang.StringUtils.isNotBlank(code)) {
//獲取token令牌
if(mark){
obj = getRroToken(portalUrl,code,clientId,clientSecret);
}else{
obj = getToken(portalUrl,code,clientId,clientSecret);
}
System.out.println("--------------------------------------------obj is:" + obj);
if(obj != null) {
accessToken = obj.getString("access_token");
new Cookie("idp_token", accessToken);
tokenType = obj.getString("token_type");
System.out.println("accessToken:" + accessToken + " tokenType:" + tokenType);
//獲取用戶信息
JSONObject json;
if(mark){
json = getProUseInfo(portalUrl, tokenType, accessToken);
}else{
json = getUseInfo(portalUrl, tokenType, accessToken);
}
if(json != null) {
System.out.println("json===" + json);
//return json.getString("screenName");
return json;
}
}
} else {
(new StringBuilder()).append("http://").append(request.getServerName()).append(":").append(request.getServerPort()).append(request.getContextPath()).toString();
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath()+"/rest/ssologin";
if(mark){
appUrl = "http://" + request.getServerName() + request.getContextPath()+"/rest/ssologin";
}
System.out.println("appUrl========="+appUrl);
String liferayDomain = portalUrl + "/o/oauth2/authorize/" + "?client_id=" + clientId;
String clientDomain = "&redirect_uri=" + URLEncoder.encode(appUrl) + "&response_type=code" + "&state=fkLiferay";
System.out.println("clientDomain encode前===&redirect_uri=" + appUrl + "&response_type=code" + "&state=fkLiferay");
System.out.println("clientDomain encode後===&redirect_uri=" + URLEncoder.encode(appUrl) + "&response_type=code" + "&state=fkLiferay");
String destUrl = liferayDomain+clientDomain;
System.out.println("destUrl===" + destUrl);
response.sendRedirect(destUrl);
}
} catch (Exception var10) {
System.out.println("e.getMessage():" + var10.getMessage());
var10.printStackTrace();
}
return null;
}
}