Commit bdbb231c authored by Quxl's avatar Quxl

x

parent d4b275f0
......@@ -18,7 +18,6 @@ import org.apache.oltu.oauth2.client.response.OAuthAuthzResponse;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import com.alibaba.fastjson.JSON;
......@@ -89,6 +88,9 @@ public interface OAuthApi {
}
/**
* <p>将系统重定向到OAuth的登陆授权页面,进行授权操作</p>
* <p>可以根据需求选择是否通过此方法进入OAuth系统进行授权</p>
* <p>可以替代此方法的方案是: 通过 getAuthorizationUrl 方法获取到OAuth授权页面的URL, 然后让用户在页面主动的点击进入OAuth进行授权</p>
*
*/
default void doRedirectOAuthLogin() {
......@@ -103,13 +105,19 @@ public interface OAuthApi {
}
}
/**
* <p>获取OAuth授权页面的URL, 用户访问此URL后会跳转到OAuth授权页面</p>
* <p>通过直接访问 doRedirectOAuthLogin 方法可以简化和替代此操作</p>
*
* @return OAuth 授权页面 URL
*/
default String getAuthorizationUrl() {
try {
OAuthConfig config = this.getOAuthConfig();
AuthenticationRequestBuilder builder = OAuthClientRequest.authorizationLocation(config.getAuthorizeUrl());
builder.setResponseType(OAuth.OAUTH_CODE);
builder.setClientId(config.getClientId());
builder.setRedirectURI(config.getRediretUrl());
builder.setRedirectURI(config.getCallbackUrl());
builder.setScope(config.getScope());
builder.setParameter("realm", config.getRealm());
OAuthClientRequest oauthResponse = builder.buildQueryMessage();
......@@ -124,6 +132,12 @@ public interface OAuthApi {
}
}
/**
* <p>用户进入OAuth系统进行授权,并授权成功后, OAuth系统会根据情况, 将页面重定向回到业务系统, 并附带OAuthToken等用户和登陆信息</p>
* <p>此方法用于解析OAuth系统授权成功回调时返回的Token信息</p>
* <p>在成功解析OAuthToken信息后,将OAuthToken信息存入HttpSession会话中</p>
*
*/
default void callback() {
try {
HttpServletRequest request = this.getHttpServletRequest();
......@@ -135,7 +149,7 @@ public interface OAuthApi {
builder.setGrantType(GrantType.AUTHORIZATION_CODE);
builder.setClientId(config.getClientId());
builder.setClientSecret(config.getClientSecret());
builder.setRedirectURI(config.getRediretUrl());
builder.setRedirectURI(config.getCallbackUrl());
builder.setCode(code);
OAuthClientRequest oauthClientRequest = builder.buildQueryMessage();
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
......@@ -155,12 +169,19 @@ public interface OAuthApi {
}
}
/**
* 保存OAuthToken信息 将token信息保存在HttpSession会话中, 登陆操作时需要调用此方法
* @param token 要保存的OAuthToken对象
*/
default void saveOAuthToken(OAuthToken token) {
HttpServletRequest request = this.getHttpServletRequest();
HttpSession session = request.getSession();
session.setAttribute(OAUTH_TOKEN_SESSION, token);
}
/**
* 从HttpSession中将OAuthToken信息删除, 注销系统时需要调用此方法进行退出操作
*/
default void removeOAuthToken() {
try {
HttpServletRequest request = this.getHttpServletRequest();
......@@ -174,6 +195,13 @@ public interface OAuthApi {
}
}
/**
* <p>刷新OAuthToken</p>
* <p>OAuthToken可能会过期,有效期具体时长暂不清楚(甲方未提供)</p>
* <p>一旦出现token过期的情况,可调用此方法进行刷新</p>
* <p>此方法的具体操作就是通过refresh_token去更新access_token, 通常情况下, refresh_token的有效期时长,会比access_token的有效期时长长很多</p>
* <p>如果refresh_token也过期了,那么就需要通过 doRedirectOAuthLogin 进行重新授权了</p>
*/
default void refreshOAuthToken() {
try {
HttpServletRequest request = this.getHttpServletRequest();
......@@ -198,7 +226,7 @@ public interface OAuthApi {
String tokenType = oAuthResponse.getTokenType();
OAuthToken newToken = new OAuthToken(accessToken, refreshToken, idToken, tokenType, expiresIn);
logger.debug("oauth refresh result: " + JSON.toJSONString(newToken));
session.setAttribute(OAUTH_TOKEN_SESSION, newToken);
this.saveOAuthToken(newToken);
} catch (OAuthApiException e) {
throw e;
} catch (Throwable e) {
......@@ -206,11 +234,23 @@ public interface OAuthApi {
}
}
/**
* 系统授权成功后,用户和通过此方法访问应用接口(因甲方未提供相关接口请求数据格式和鉴权设置等信息, 此处只按标准OAuth授权后的请求流程进行操作, 如有出入,用户可以根据实际情况, 重写或重载此方法)
* @param url 访问URL
* @param headers HTTP头信息
* @param data HTTP请求参数
* @return HTTP请求响应结果
*/
default String doPost(String url, Map<String, String> headers, JSONObject data) {
try {
logger.debug("oauth post url: " + url);
logger.debug("oauth post headers: " + JSON.toJSONString(headers));
logger.debug("oauth post data: " + data.toJSONString());
OAuthToken token = this.getOAuthToken();
if(System.currentTimeMillis() - token.getCreateMillis() > ((token.getExpiresIn()-5) * 1000)) {
this.refreshOAuthToken();
token = this.getOAuthToken();
}
String accept = "application/json";
String requestId = ("" + System.currentTimeMillis());
String countryCode = System.getProperty("X-SE-IFW-CountryCode");
......@@ -221,9 +261,6 @@ public interface OAuthApi {
headers.put("X-SE-IFW-CountryCode", countryCode);
headers.put("X-SE-IFW-LanguageCode", languageCode);
headers.put("X-SE-IFW-ApplicationName", applicationName);
HttpServletRequest request = this.getHttpServletRequest();
HttpSession session = request.getSession();
OAuthToken token = (OAuthToken)session.getAttribute(OAUTH_TOKEN_SESSION);
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
String accessToken = token.getAccessToken();
OAuthClientRequest clientRequest = new OAuthBearerClientRequest(url).setAccessToken(accessToken).buildQueryMessage();
......@@ -235,12 +272,12 @@ public interface OAuthApi {
return resBody;
} catch (OAuthApiException e) {
throw e;
} catch (OAuthProblemException e) {
this.refreshOAuthToken();
return doPost(url, headers, data);
} catch (Throwable e) {
throw new OAuthApiException(e.getMessage(), e);
}
}
public static void main(String[] args) {
System.out.println(3599/60);
}
}
package com.egolm.sso.oauth;
/**
* 自定义异常类
* @author Quxl
*
*/
public class OAuthApiException extends RuntimeException {
private static final long serialVersionUID = 4300677142149830999L;
......
......@@ -8,12 +8,39 @@ public class OAuthConfig implements Serializable {
private static final long serialVersionUID = 1874417633433974015L;
/**
* realm
*/
private String realm = "/se";
/**
* scope
*/
private String scope = "openid profile";
/**
* OAuth系统提供 client_id
*/
private String clientId;
/**
* OAuth系统提供 client_secret
*/
private String clientSecret;
private String rediretUrl;
/**
* 系统授权完成后的回调地址(业务系统提供)
*/
private String callbackUrl;
/**
* OAuth系统提供,用于进行访问授权
*/
private String authorizeUrl;
/**
* OAuth系统提供,用户获取或刷新access_token
*/
private String accessTokenUrl;
public String getClientId() {
......@@ -48,14 +75,6 @@ public class OAuthConfig implements Serializable {
this.accessTokenUrl = accessTokenUrl;
}
public String getRediretUrl() {
return rediretUrl;
}
public void setRediretUrl(String rediretUrl) {
this.rediretUrl = rediretUrl;
}
public String toString() {
return JSON.toJSONString(this, true);
}
......@@ -80,4 +99,12 @@ public class OAuthConfig implements Serializable {
return serialVersionUID;
}
public String getCallbackUrl() {
return callbackUrl;
}
public void setCallbackUrl(String callbackUrl) {
this.callbackUrl = callbackUrl;
}
}
......@@ -10,18 +10,40 @@ public class OAuthToken implements Serializable {
private static final long serialVersionUID = -73234152183180980L;
/**
* access_token
*/
private String accessToken;
/**
* refresh_token, 有效期比access_token长, 可用于刷新access_token
*/
private String refreshToken;
/**
* id_token
*/
private String idToken;
/**
* token类型
*/
private String tokenType;
/**
* 过期时间
*/
private Long expiresIn;
private Long createMillis;
public OAuthToken(String accessToken, String refreshToken, String idToken, String tokenType, Long expiresIn) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.idToken = idToken;
this.tokenType = tokenType;
this.expiresIn = expiresIn;
this.createMillis = System.currentTimeMillis();
}
public String getAccessToken() {
......@@ -48,7 +70,10 @@ public class OAuthToken implements Serializable {
return serialVersionUID;
}
public Long getCreateMillis() {
return createMillis;
}
public static void main(String[] args) {
String str = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdF9oYXNoIjoiczBtRHJvLUxBQXRLMnFDRWdtSWM3dyIsIkVtYWlsIjoicGFydGhhc2FyYXRoaS5wYWxAbWFpbGluYXRvci5jb20iLCJpbmR1c3RyeVNlZ21lbnQiOiJJRDUiLCJwb3N0YWxDb2RlIjoiNDM0NDIiLCJjb21wYW55U3RhdGUiOiJBSCIsImlzcyI6Imh0dHBzOi8vaWRlbnRpdHktc3RnLnNjaG5laWRlci1lbGVjdHJpYy5jb206NDQzL2FjY2Vzc21hbmFnZXIvb2F1dGgyL3NlIiwiY291bnR5IjoiSW5kaWEiLCJjb21wYW55U3RyZWV0IjoiamIiLCJjdXN0b21fYXR0cmlidXRlcyI6eyJlbWFpbCI6InBhcnRoYXNhcmF0aGkucGFsQG1haWxpbmF0b3IuY29tIiwiRW1haWwiOiJwYXJ0aGFzYXJhdGhpLnBhbEBtYWlsaW5hdG9yLmNvbSIsIkNvdW50cnkiOiJDTiIsImZlZGVyYXRlZElkIjoiY24wMFpPanctZTJjZS1HNW44LTZ0U3EtWVdiOUIyMW1NbkFWIiwiRmlyc3ROYW1lIjoicGFydGhhc2FyYXRoaSIsImZpcnN0TmFtZSI6InBhcnRoYXNhcmF0aGkiLCJsYXN0TmFtZSI6InBhbCIsIkxhc3ROYW1lIjoicGFsIiwiY2xhc3NMZXZlbDEiOiJFVSIsImNsYXNzTGV2ZWwyIjpudWxsfSwicmVnaXN0ZXJhdGlvblNvdXJjZSI6Im9hdXRoU2FtcGxlQXBwIiwiQ29tcGFueU5hbWUiOiJpbiIsImF1dGhfdGltZSI6MTU2MzI1NjQ3OCwiYWRkaXRpb25hbEluZm8iOiJ0ZXN0IiwiY29tcGFueUNvdW50cnkiOiJDTiIsIklETVNVSUQiOiJwYXJ0aGFzYXJhdGhpLnBhbEBtYWlsaW5hdG9yLmNvbSIsImV4cCI6MTU2MzI2MDA4NSwiY29tcGFueVBvc3RhbENvZGUiOiI3ODk5NzY2IiwiY2xhc3NMZXZlbDEiOiJFVSIsImNvbXBhbnlDaXR5Ijoiam4iLCJGZWRlcmF0ZWRJZCI6ImNuMDBaT2p3LWUyY2UtRzVuOC02dFNxLVlXYjlCMjFtTW5BViIsImlzSW50ZXJuYWwiOiJGQUxTRSIsImF1ZCI6Im15Q2xpZW50SUQiLCJjX2hhc2giOiJFSlFoWjNsc29YUnI2bjhxallkXzJRIiwiZmlyc3ROYW1lIjoicGFydGhhc2FyYXRoaSIsIm9yZy5mb3JnZXJvY2sub3BlbmlkY29ubmVjdC5vcHMiOiJmMWYxMDc4Yy04ZDRlLTQwNTQtYjQ2Zi1kODQ3N2I5MDQ1NWIiLCJuYW1lIjoicHBwcHAiLCJwcmVmZXJyZWRsYW5ndWFnZSI6ImVuIiwiQ291bnRyeSI6IkNOIiwiTGFzdE5hbWUiOiJwYWwiLCJ0b2tlblR5cGUiOiJKV1RUb2tlbiIsImZlZGVyYXRpb25JRCI6ImNuMDBaT2p3LWUyY2UtRzVuOC02dFNxLVlXYjlCMjFtTW5BViIsIklETVNpc0ludGVybmFsX19jIjoiRkFMU0UiLCJzdWIiOiJjbjAwWk9qdy1lMmNlLUc1bjgtNnRTcS1ZV2I5QjIxbU1uQVYiLCJsYXN0TmFtZSI6InBhbCIsIkFJTF9BcHBsaWNhdGlvbiI6Im9hdXRoU2FtcGxlQXBwLEF1dG9tYXRpb25Ib21lLEFwcCIsInByZWZlcnJlZExhbmd1YWdlIjoiZW4iLCJhaWwiOiIoQXBwbGljYXRpb247b2F1dGhTYW1wbGVBcHAsQXV0b21hdGlvbkhvbWUsQXBwKSIsImF1ZGl0VHJhY2tpbmdJZCI6ImQ2ZDMzNTllLWU5MWItNDJmMi05OTc1LWUwNzhmOGE4MWRmMy04MjE3IiwidG9rZW5OYW1lIjoiaWRfdG9rZW4iLCJlbWFpbE9wdEluIjoiTiIsImNvbXBhbnlGZWRlcmF0ZWRJRCI6ImNuMDBaU2ExLUJrQXctalVCZi1NYmdiLVZucE8zQ0t4bUQ3TyIsIkFJTHMiOiIoQXBwbGljYXRpb247b2F1dGhTYW1wbGVBcHAsQXV0b21hdGlvbkhvbWUsQXBwKSIsImhlYWRxdWFydGVyIjoiZmFsc2UiLCJhenAiOiJteUNsaWVudElEIiwic3RyZWV0IjoiSGFudHZlcmtzZ2F0YW4yOCIsImN1cnJlbmN5IjoiQ05ZIiwiaWF0IjoxNTYzMjU2NDg1LCJlbWFpbCI6InBhcnRoYXNhcmF0aGkucGFsQG1haWxpbmF0b3IuY29tIiwiYyI6IkNOIiwiRmlyc3ROYW1lIjoicGFydGhhc2FyYXRoaSIsIm1vYmlsZSI6IjcwMjEwMTAxMDEwIiwibCI6Ikt1bmdzYmFja2EiLCJnaXZlbl9uYW1lIjoicGFydGhhc2FyYXRoaSIsImFpbF9hcHBsaWNhdGlvbnMiOiJvYXV0aFNhbXBsZUFwcCxBdXRvbWF0aW9uSG9tZSxBcHAiLCJlbXBsb3llZVR5cGUiOiJAV29yayIsInVwZGF0ZVNvdXJjZSI6IlVpbXMiLCJmZWRlcmF0ZWRJZCI6ImNuMDBaT2p3LWUyY2UtRzVuOC02dFNxLVlXYjlCMjFtTW5BViIsInJlYWxtIjoiL3NlIiwiaW5ldFVzZXJTdGF0dXMiOiJBY3RpdmUiLCJmYW1pbHlfbmFtZSI6InBhbCJ9.yly0EYywEjkVtXwrrlH8_dZ62YqFDxoEjX5uGpbg8C4";
String[] strs = str.split("\\.");
......@@ -57,4 +82,5 @@ public class OAuthToken implements Serializable {
System.out.println(strs[2]);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment