/* * 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.provider; import com.fujieid.jap.ids.model.*; import com.fujieid.jap.ids.service.Oauth2Service; import com.fujieid.jap.ids.util.OauthUtil; import com.fujieid.jap.ids.util.ObjectUtils; import com.fujieid.jap.ids.util.TokenUtil; import com.xkcoding.json.util.StringUtil; import java.util.HashMap; import java.util.Map; /** * Authorize the endpoint to create a callback url, and pass different callback parameters according to the request parameters * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0.0 * @since 1.0.0 */ public class IdsAuthorizationProvider { private final Oauth2Service oauth2Service; public IdsAuthorizationProvider(Oauth2Service oauth2Service) { this.oauth2Service = oauth2Service; } /** * 4.2. Implicit Grant * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String * @see 4.2. Implicit Grant */ public String generateImplicitGrantResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { AccessToken accessToken = TokenUtil.createAccessToken(userInfo, clientDetail, param.getGrantType(), param.getScope(), param.getNonce(), issuer); Map tokenResponse = new HashMap<>(9); // https://tools.ietf.org/html/rfc6749#section-4.2.2 // The authorization server MUST NOT issue a refresh token. tokenResponse.put(IdsConsts.ACCESS_TOKEN, accessToken.getAccessToken()); tokenResponse.put(IdsConsts.EXPIRES_IN, String.valueOf(OauthUtil.getAccessTokenExpiresIn(clientDetail.getAccessTokenExpiresIn()))); tokenResponse.put(IdsConsts.TOKEN_TYPE, IdsConsts.TOKEN_TYPE_BEARER); tokenResponse.put(IdsConsts.SCOPE, param.getScope()); if (OauthUtil.isOidcProtocol(param.getScope())) { tokenResponse.put(IdsConsts.ID_TOKEN, TokenUtil.createIdToken(clientDetail, userInfo, param.getNonce(), issuer)); } if (StringUtil.isNotEmpty(param.getState())) { tokenResponse.put(IdsConsts.STATE, param.getState()); } String params = ObjectUtils.parseMapToString(tokenResponse, false); return param.getRedirectUri() + "?" + params; } /** * 4.1. Authorization Code Grant * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @return String * @see 4.1. Authorization Code Grant */ public String generateAuthorizationCodeResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail) { String authorizationCode = oauth2Service.createAuthorizationCode(param, userInfo, OauthUtil.getCodeExpiresIn(clientDetail.getCodeExpiresIn())); String params = "?code=" + authorizationCode; if (StringUtil.isNotEmpty(param.getState())) { params = params + "&state=" + param.getState(); } return param.getRedirectUri() + params; } /** * When the value of {@code response_type} is {@code code id_token}, return {@code code} and {@code id_token} from the authorization endpoint * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String * @see Definitions of Multiple-Valued Response Type Combinations */ public String generateCodeIdTokenAuthorizationResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { String params = "&id_token=" + TokenUtil.createIdToken(clientDetail, userInfo, param.getNonce(), issuer); return this.generateAuthorizationCodeResponse(userInfo, param, clientDetail) + params; } /** * When the value of {@code response_type} is {@code id_token}, an {@code id_token} is returned from the authorization endpoint. * This mode does not require the use of token endpoints. * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String */ public String generateIdTokenAuthorizationResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { String params = "?id_token=" + TokenUtil.createIdToken(clientDetail, userInfo, param, issuer); return param.getRedirectUri() + params; } /** * When the value of {@code response_type} is {@code id_token token}, the {@code id_token} and {@code access_token} are returned from the authorization endpoint. * This mode does not require the use of token endpoints. * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String * @see Definitions of Multiple-Valued Response Type Combinations */ public String generateIdTokenTokenAuthorizationResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { AccessToken accessToken = TokenUtil.createAccessToken(userInfo, clientDetail, param.getGrantType(), param.getScope(), param.getNonce(), issuer); String params = "?access_token=" + accessToken.getAccessToken() + "&id_token=" + TokenUtil.createIdToken(clientDetail, userInfo, param.getNonce(), issuer); return param.getRedirectUri() + params; } /** * When the value of {@code response_type} is {@code code token}, return {@code code} and {@code token} from the authorization endpoint * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String * @see Definitions of Multiple-Valued Response Type Combinations */ public String generateCodeTokenAuthorizationResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { AccessToken accessToken = TokenUtil.createAccessToken(userInfo, clientDetail, param.getGrantType(), param.getScope(), param.getNonce(), issuer); String params = "&access_token=" + accessToken.getAccessToken(); return this.generateAuthorizationCodeResponse(userInfo, param, clientDetail) + params; } /** * When the value of {@code response_type} is {@code code id_token token}, return {@code code},{@code id_token} and {@code token} from the authorization endpoint * * @param userInfo Logged-in user information * @param param Request parameter * @param clientDetail Application information * @param issuer The issuer name. This parameter cannot contain the colon (:) character. * @return String * @see Definitions of Multiple-Valued Response Type Combinations */ public String generateCodeIdTokenTokenAuthorizationResponse(UserInfo userInfo, IdsRequestParam param, ClientDetail clientDetail, String issuer) { String params = "&id_token=" + TokenUtil.createIdToken(clientDetail, userInfo, param.getNonce(), issuer); return this.generateCodeTokenAuthorizationResponse(userInfo, param, clientDetail, issuer) + params; } /** * When the value of {@code response_type} is {@code none}, the {@code code},{@code id_token} and {@code token} is not returned from the authorization endpoint, * if there is a state, it is returned as it is. * * @param param Request parameter * @return String * @see None Response Type */ public String generateNoneAuthorizationResponse(IdsRequestParam param) { String params = ""; if (!StringUtil.isEmpty(param.getState())) { params = "?state=" + param.getState(); } return param.getRedirectUri() + params; } }