/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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.fujitsu.dc.core; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import org.apache.http.HttpStatus; import org.json.simple.JSONObject; import com.fujitsu.dc.core.DcCoreMessageUtils.Severity; import com.fujitsu.dc.core.auth.OAuth2Helper.Error; import com.fujitsu.dc.core.auth.OAuth2Helper.Key; import com.fujitsu.dc.core.auth.OAuth2Helper.Scheme; /** * ログメッセージ作成クラス. */ /** * @author naoki */ @SuppressWarnings("serial") public final class DcCoreAuthnException extends DcCoreException { /** * Grant-Typeの値が異常. */ public static final DcCoreAuthnException UNSUPPORTED_GRANT_TYPE = create("PR400-AN-0001", Error.UNSUPPORTED_GRANT_TYPE); /** * dc_targetの値異常. */ public static final DcCoreAuthnException INVALID_TARGET = create("PR400-AN-0002", Error.INVALID_REQUEST); /** * Client Sercret パースエラー. */ public static final DcCoreAuthnException CLIENT_SERCRET_PARSE_ERROR = create("PR400-AN-0003", Error.INVALID_CLIENT); /** * Client Sercret 有効期限チェック. */ public static final DcCoreAuthnException CLIENT_SERCRET_EXPIRED = create("PR400-AN-0004", Error.INVALID_CLIENT); /** * Client Sercret 署名検証をエラー. */ public static final DcCoreAuthnException CLIENT_SERCRET_DSIG_INVALID = create("PR400-AN-0005", Error.INVALID_CLIENT); /** * Client Sercret のIssuerがIDと等しくない. */ public static final DcCoreAuthnException CLIENT_SERCRET_ISSUER_MISMATCH = create("PR400-AN-0006", Error.INVALID_CLIENT); /** * Client Sercret のターゲットが自分でない. */ public static final DcCoreAuthnException CLIENT_SERCRET_TARGET_WRONG = create("PR400-AN-0007", Error.INVALID_CLIENT); /** * トランスセルトークン認証ではユニットユーザ昇格はできない. */ public static final DcCoreAuthnException TC_ACCESS_REPRESENTING_OWNER = create("PR400-AN-0008", Error.INVALID_GRANT); /** * トークンパースエラー. */ public static final DcCoreAuthnException TOKEN_PARSE_ERROR = create("PR400-AN-0009", Error.INVALID_GRANT); /** * 有効期限切れ. */ public static final DcCoreAuthnException TOKEN_EXPIRED = create("PR400-AN-0010", Error.INVALID_GRANT); /** * 署名検証をエラー. */ public static final DcCoreAuthnException TOKEN_DSIG_INVALID = create("PR400-AN-0011", Error.INVALID_GRANT); /** * トークン のターゲットが自分でない. * {0}:トークンのターゲットURL */ public static final DcCoreAuthnException TOKEN_TARGET_WRONG = create("PR400-AN-0012", Error.INVALID_GRANT); /** * リフレッシュトークンでない. */ public static final DcCoreAuthnException NOT_REFRESH_TOKEN = create("PR400-AN-0013", Error.INVALID_GRANT); /** * 権限がないから昇格できない. */ public static final DcCoreAuthnException NOT_ALLOWED_REPRESENT_OWNER = create("PR400-AN-0014", Error.INVALID_GRANT); /** * オーナーがいないセルは昇格できない. */ public static final DcCoreAuthnException NO_CELL_OWNER = create("PR400-AN-0015", Error.INVALID_GRANT); /** * 必須パラメータが無い. * {0}:パラメータキー名 */ public static final DcCoreAuthnException REQUIRED_PARAM_MISSING = create("PR400-AN-0016", Error.INVALID_REQUEST); /** * 認証エラー. */ public static final DcCoreAuthnException AUTHN_FAILED = create("PR400-AN-0017", Error.INVALID_GRANT); /** * 認証ヘッダの指定誤り. */ public static final DcCoreAuthnException AUTH_HEADER_IS_INVALID = create("PR400-AN-0018", Error.INVALID_CLIENT); /** * Accountロック中. */ public static final DcCoreAuthnException ACCOUNT_LOCK_ERROR = create("PR400-AN-0019", Error.INVALID_GRANT); /** * IDTokenの検証の中で、受け取ったIdTokenのAudienceが信頼するClientIDのリストに無かった. */ public static final DcCoreAuthnException OIDC_WRONG_AUDIENCE = create("PR400-AN-0030", Error.INVALID_GRANT); /** * OIDCの認証エラー. */ public static final DcCoreAuthnException OIDC_AUTHN_FAILED = create("PR400-AN-0031", Error.INVALID_GRANT); /** * 無効なIDToken. */ public static final DcCoreAuthnException OIDC_INVALID_ID_TOKEN = create("PR400-AN-0032", Error.INVALID_GRANT); /** * IDTokenの有効期限切れ. */ public static final DcCoreAuthnException OIDC_EXPIRED_ID_TOKEN = create("PR400-AN-0033", Error.INVALID_GRANT); /** * インナークラスを強制的にロードする. */ public static void loadConfig() { } String error; String realm; /** * コンストラクタ. * @param status HTTPレスポンスステータス * @param severityエラーレベル * @param code エラーコード * @param message エラーメッセージ * @param error OAuth認証エラーのエラーコード * @param realm WWWW-Authenticateヘッダを返す場合はここにrealm値を設定する */ DcCoreAuthnException(final String code, final Severity severity, final String message, final int status, final String error, final String realm) { super(code, severity, message, status); this.error = error; this.realm = realm; } /** * realmを設定してオブジェクト生成. * @param realm2set realm * @return CoreAuthnException */ public DcCoreAuthnException realm(String realm2set) { // クローンを作成 return new DcCoreAuthnException(this.code, this.severity, this.message, this.status, this.error, realm2set); } @SuppressWarnings("unchecked") @Override public Response createResponse() { JSONObject errorJson = new JSONObject(); errorJson.put(Key.ERROR, this.error); String errDesc = String.format("[%s] - %s", this.code, this.message); errorJson.put(Key.ERROR_DESCRIPTION, errDesc); int statusCode = parseCode(this.code); ResponseBuilder rb = Response.status(statusCode) .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) .entity(errorJson.toJSONString()); // レルム値が設定されていれば、WWW-Authenticateヘッダーを返却する。 // __authエンドポイントでは、認証失敗時(401返却時)には、同ヘッダーに Auth SchemeがBasicの値を返却するため、ここでは固定値とする。 if (this.realm != null && statusCode == HttpStatus.SC_UNAUTHORIZED) { rb = rb.header(HttpHeaders.WWW_AUTHENTICATE, Scheme.BASIC + " realm=\"" + this.realm + "\""); } return rb.build(); } /** * 原因例外を追加したものを作成して返します. * @param t 原因例外 * @return DcCoreException */ public DcCoreException reason(final Throwable t) { // クローンを作成して DcCoreException ret = new DcCoreAuthnException( this.code, this.severity, this.message, this.status, this.error, this.realm); // スタックトレースをセット ret.setStackTrace(t.getStackTrace()); return ret; } /** * ファクトリーメソッド. * @param code DCメッセージコード * @param error OAuth2エラーコード * @return DcCoreException */ public static DcCoreAuthnException create(String code, String error) { int statusCode = DcCoreException.parseCode(code); // ログレベルの取得 Severity severity = DcCoreMessageUtils.getSeverity(code); if (severity == null) { // ログレベルが設定されていなかったらレスポンスコードから自動的に判定する。 severity = decideSeverity(statusCode); } // ログメッセージの取得 String message = DcCoreMessageUtils.getMessage(code); return new DcCoreAuthnException(code, severity, message, statusCode, error, null); } }