/* * Copyright (c) 2020-2040, 北京符节科技有限公司 (support@fujieid.com & https://www.fujieid.com). *

* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.gnu.org/licenses/lgpl.html *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fujieid.jap.ids.util; import cn.hutool.core.util.ObjectUtil; import com.fujieid.jap.http.JapHttpRequest; import com.fujieid.jap.http.RequestUtil; import com.fujieid.jap.ids.JapIds; import com.fujieid.jap.ids.exception.IdsTokenException; import com.fujieid.jap.ids.exception.InvalidTokenException; import com.fujieid.jap.ids.model.*; import com.fujieid.jap.ids.model.enums.ErrorResponse; import com.fujieid.jap.ids.model.enums.TokenAuthMethod; import com.fujieid.jap.ids.service.IdsTokenService; import com.xkcoding.json.util.StringUtil; import java.io.Serializable; import java.util.Collections; import java.util.Date; import java.util.List; /** * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0.0 * @since 1.0.0 */ public class TokenUtil { /** * Get access token from request * * @param request request * @return String */ public static String getAccessToken(JapHttpRequest request) { List tokenAuthMethods = JapIds.getIdsConfig().getTokenAuthMethods(); if (ObjectUtil.isEmpty(tokenAuthMethods)) { tokenAuthMethods = Collections.singletonList(TokenAuthMethod.ALL); } if (tokenAuthMethods.contains(TokenAuthMethod.ALL)) { String accessToken = getAccessTokenFromUrl(request); if (StringUtil.isEmpty(accessToken)) { accessToken = getAccessTokenFromHeader(request); if (StringUtil.isEmpty(accessToken)) { accessToken = getAccessTokenFromCookie(request); } } return accessToken; } else { if (tokenAuthMethods.contains(TokenAuthMethod.TOKEN_URL)) { String accessToken = getAccessTokenFromUrl(request); if (accessToken != null) { return accessToken; } } if (tokenAuthMethods.contains(TokenAuthMethod.TOKEN_HEADER)) { String accessToken = getAccessTokenFromHeader(request); if (accessToken != null) { return accessToken; } } if (tokenAuthMethods.contains(TokenAuthMethod.TOKEN_COOKIE)) { return getAccessTokenFromCookie(request); } } return null; } private static String getAccessTokenFromUrl(JapHttpRequest request) { String accessToken = RequestUtil.getParam(IdsConsts.ACCESS_TOKEN, request); if (StringUtil.isNotEmpty(accessToken)) { return accessToken; } return null; } private static String getAccessTokenFromHeader(JapHttpRequest request) { String accessToken = RequestUtil.getHeader(IdsConsts.AUTHORIZATION_HEADER_NAME, request); return BearerToken.parse(accessToken); } private static String getAccessTokenFromCookie(JapHttpRequest request) { return RequestUtil.getCookieVal(request, IdsConsts.ACCESS_TOKEN); } public static String createIdToken(ClientDetail clientDetail, UserInfo user, String nonce, String issuer) { long idTokenExpiresIn = OauthUtil.getIdTokenExpiresIn(clientDetail.getIdTokenExpiresIn()); return JwtUtil.createJwtToken(clientDetail.getClientId(), user, idTokenExpiresIn, nonce, issuer); } public static String createIdToken(ClientDetail clientDetail, UserInfo user, IdsRequestParam param, String issuer) { long idTokenExpiresIn = OauthUtil.getIdTokenExpiresIn(clientDetail.getIdTokenExpiresIn()); return JwtUtil.createJwtToken(clientDetail.getClientId(), user, idTokenExpiresIn, param.getNonce(), OauthUtil.convertStrToList(param.getScope()), param.getResponseType(), issuer); } public static AccessToken createAccessToken(UserInfo user, ClientDetail clientDetail, String grantType, String scope, String nonce, String issuer) { String clientId = clientDetail.getClientId(); long accessTokenExpiresIn = OauthUtil.getAccessTokenExpiresIn(clientDetail.getAccessTokenExpiresIn()); long refreshTokenExpiresIn = OauthUtil.getRefreshTokenExpiresIn(clientDetail.getRefreshTokenExpiresIn()); IdsTokenService tokenService = JapIds.getContext().getTokenService(); if (null == tokenService) { throw new IdsTokenException("com.fujieid.jap.ids.service.IdsTokenService has not been injected"); } String accessTokenStr = tokenService.createAccessToken(clientId, user, accessTokenExpiresIn, nonce, issuer, null); String refreshTokenStr = tokenService.createRefreshToken(clientId, OauthUtil.convertStrToList(scope)); AccessToken accessToken = new AccessToken(); accessToken.setAccessToken(accessTokenStr); accessToken.setRefreshToken(refreshTokenStr); accessToken.setGrantType(grantType); if (null != user) { accessToken.setUserName(user.getUsername()); accessToken.setUserId(user.getId()); } accessToken.setClientId(clientId); accessToken.setScope(scope); accessToken.setRefreshTokenExpiresIn(refreshTokenExpiresIn); accessToken.setAccessTokenExpiresIn(accessTokenExpiresIn); accessToken.setAccessTokenExpiration(OauthUtil.getAccessTokenExpiresAt(accessTokenExpiresIn)); accessToken.setRefreshTokenExpiration(OauthUtil.getRefreshTokenExpiresAt(refreshTokenExpiresIn)); String tokenCacheKey = IdsConsts.OAUTH_ACCESS_TOKEN_CACHE_KEY + accessTokenStr; String rtokenCacheKey = IdsConsts.OAUTH_REFRESH_TOKEN_CACHE_KEY + refreshTokenStr; JapIds.getContext().getCache().set(tokenCacheKey, accessToken, accessTokenExpiresIn * 1000); JapIds.getContext().getCache().set(rtokenCacheKey, accessToken, refreshTokenExpiresIn * 1000); return accessToken; } public static AccessToken refreshAccessToken(UserInfo user, ClientDetail clientDetail, AccessToken accessToken, String nonce, String issuer) { String rawToken = accessToken.getAccessToken(); Long accessTokenExpiresIn = OauthUtil.getAccessTokenExpiresIn(clientDetail.getAccessTokenExpiresIn()); IdsTokenService tokenService = JapIds.getContext().getTokenService(); if (null == tokenService) { throw new IdsTokenException("com.fujieid.jap.ids.service.IdsTokenService has not been injected"); } String accessTokenStr = tokenService.createAccessToken(clientDetail.getClientId(), user, accessTokenExpiresIn, nonce, issuer, null); accessToken.setAccessToken(accessTokenStr); accessToken.setAccessTokenExpiresIn(accessTokenExpiresIn); accessToken.setAccessTokenExpiration(OauthUtil.getAccessTokenExpiresAt(accessTokenExpiresIn)); String tokenCacheKey = IdsConsts.OAUTH_ACCESS_TOKEN_CACHE_KEY + accessTokenStr; JapIds.getContext().getCache().set(tokenCacheKey, accessToken, accessTokenExpiresIn * 1000); String rawTokenCacheKey = IdsConsts.OAUTH_ACCESS_TOKEN_CACHE_KEY + rawToken; JapIds.getContext().getCache().removeKey(rawTokenCacheKey); return accessToken; } public static AccessToken createClientCredentialsAccessToken(ClientDetail clientDetail, String grantType, String scope, String nonce, String issuer) { return createAccessToken(null, clientDetail, grantType, scope, nonce, issuer); } public static void invalidateToken(JapHttpRequest request) { String accessTokenStr = TokenUtil.getAccessToken(request); AccessToken accessToken = TokenUtil.getByAccessToken(accessTokenStr); if (null != accessToken) { String token = IdsConsts.OAUTH_ACCESS_TOKEN_CACHE_KEY + accessTokenStr; String rtoken = IdsConsts.OAUTH_REFRESH_TOKEN_CACHE_KEY + accessToken.getRefreshToken(); JapIds.getContext().getCache().removeKey(token); JapIds.getContext().getCache().removeKey(rtoken); } } public static void validateAccessToken(String accessToken) { AccessToken token = getByAccessToken(accessToken); if (token == null) { throw new InvalidTokenException(ErrorResponse.INVALID_TOKEN); } Date nowDate = new Date(); if (token.getAccessTokenExpiration().before(nowDate)) { throw new InvalidTokenException(ErrorResponse.EXPIRED_TOKEN); } } public static void validateRefreshToken(String refreshToken) { AccessToken token = getByRefreshToken(refreshToken); if (token == null) { throw new InvalidTokenException(ErrorResponse.INVALID_TOKEN); } Date nowDate = new Date(); if (token.getRefreshTokenExpiration().before(nowDate)) { throw new InvalidTokenException(ErrorResponse.EXPIRED_TOKEN); } } public static AccessToken getByAccessToken(String accessToken) { if (null == accessToken) { return null; } accessToken = BearerToken.parse(accessToken); String token = IdsConsts.OAUTH_ACCESS_TOKEN_CACHE_KEY + accessToken; Serializable serializable = JapIds.getContext().getCache().get(token); return OauthUtil.objToBean(serializable, AccessToken.class); } public static AccessToken getByRefreshToken(String refreshToken) { if (null == refreshToken) { return null; } String token = IdsConsts.OAUTH_REFRESH_TOKEN_CACHE_KEY + refreshToken; Serializable serializable = JapIds.getContext().getCache().get(token); return OauthUtil.objToBean(serializable, AccessToken.class); } }