/// <summary>CreateByRsa</summary> /// <param name="iss">client_id</param> /// <param name="aud">Token2 EndPointのuri</param> /// <param name="forExp">DateTimeOffset</param> /// <param name="scopes">scopes</param> /// <param name="rsaPrivateKey">RS256用のRSAParameters秘密鍵</param> /// <returns>JwtAssertion</returns> public static string CreateByRsa( string iss, string aud, TimeSpan forExp, string scopes, RSAParameters rsaPrivateKey) { string json = ""; //string jws = ""; #region ClaimSetの生成 Dictionary <string, object> jwtAssertionClaimSet = new Dictionary <string, object>(); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iss, iss); // client_id jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.aud, aud); // Token EndPointのuri。 jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.exp, CmnJwtToken.CreateExpClaim(forExp)); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iat, CmnJwtToken.CreateIatClaim()); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.jti, CmnJwtToken.CreateJitClaim()); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.scope, scopes); // scopes json = JsonConvert.SerializeObject(jwtAssertionClaimSet); #endregion #region JWT化 JWS_RS256_Param jwtRS256 = new JWS_RS256_Param(rsaPrivateKey); return(jwtRS256.Create(json)); #endregion }
/// <summary>CreateByECDsa</summary> /// <param name="iss">client_id</param> /// <param name="aud">Token2 EndPointのuri</param> /// <param name="forExp">DateTimeOffset</param> /// <param name="scopes">scopes</param> /// <param name="ecdsaX509FilePath">ES256用の X.509秘密鍵 の File Path</param> /// <param name="ecdsaX509Password">ES256用の X.509秘密鍵 の Password</param> /// <returns>JwtAssertion</returns> public static string CreateByECDsa( string iss, string aud, TimeSpan forExp, string scopes, string ecdsaX509FilePath, string ecdsaX509Password) ///// <param name="eccPrivateKey">ES256用のECParameters秘密鍵</param> //ECParameters ecPrivateKey) // ECDsa.ExportParameters(true)が動かねぇ。 { string json = ""; //string jws = ""; #region ClaimSetの生成 Dictionary <string, object> jwtAssertionClaimSet = new Dictionary <string, object>(); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iss, iss); // client_id jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.aud, aud); // Token EndPointのuri。 jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.exp, CmnJwtToken.CreateExpClaim(forExp)); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.iat, CmnJwtToken.CreateIatClaim()); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.jti, CmnJwtToken.CreateJitClaim()); jwtAssertionClaimSet.Add(OAuth2AndOIDCConst.scope, scopes); // scopes json = JsonConvert.SerializeObject(jwtAssertionClaimSet); #endregion #region JWT化 JWS_ES256_X509 jwtES256 = new JWS_ES256_X509(ecdsaX509FilePath, ecdsaX509Password); return(jwtES256.Create(json)); #endregion }
// - OpenID Connect Client Initiated Backchannel Authentication Flow - Core 1.0 draft-01 // https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html // - Financial-grade API: Client Initiated Backchannel Authentication Profile // https://openid.net/specs/openid-financial-api-ciba-ID1.html #region Create ///// <summary>CreateCiba</summary> ///// <param name="iss">string</param> ///// <param name="aud">string</param> ///// <param name="exp">string</param> ///// <param name="nbf">string</param> ///// <param name="scopes">string</param> ///// <param name="client_notification_token">string</param> ///// <param name="binding_message">string</param> ///// <param name="user_code">string</param> ///// <param name="requested_expiry">string</param> ///// <param name="login_hint">string</param> ///// <param name="requestContextAndIntent">Dictionary(string, object)</param> ///// <param name="jwkPrivateKey">ES256用のJWK秘密鍵</param> ///// <returns>RequestObject</returns> //public static string CreateCiba( // string iss, string aud, string exp, string nbf, string scopes, // string client_notification_token, string binding_message, // string user_code, string requested_expiry, string login_hint, // Dictionary<string, object> requestContextAndIntent, string jwkPrivateKey) //{ // EccPrivateKeyConverter epkc = new EccPrivateKeyConverter(); // return RequestObject.CreateCiba( // iss, aud, exp, nbf, scopes, // client_notification_token, binding_message, // user_code, requested_expiry, login_hint, // requestContextAndIntent, epkc.JwkToParam(jwkPrivateKey)); //} /// <summary>CreateCiba</summary> /// <param name="iss">string</param> /// <param name="aud">string</param> /// <param name="exp">string</param> /// <param name="nbf">string</param> /// <param name="scopes">string</param> /// <param name="client_notification_token">string</param> /// <param name="binding_message">string</param> /// <param name="user_code">string</param> /// <param name="requested_expiry">string</param> /// <param name="login_hint">string</param> /// <param name="requestContextAndIntent">Dictionary(string, object)</param> /// <param name="ecdsaX509FilePath">ES256用の X.509秘密鍵 の File Path</param> /// <param name="ecdsaX509Password">ES256用の X.509秘密鍵 の Password</param> /// <returns>RequestObject</returns> public static string CreateCiba( string iss, string aud, string exp, string nbf, string scopes, string client_notification_token, string binding_message, string user_code, string requested_expiry, string login_hint, Dictionary <string, object> requestContextAndIntent, string ecdsaX509FilePath, string ecdsaX509Password) ///// <param name="ecPrivateKey">ES256用のECParameters秘密鍵</param> //ECParameters ecPrivateKey) // ECDsa.ExportParameters(true)が動かねぇ。 { string json = ""; #region ClaimSetの生成 Dictionary <string, object> requestObjectClaimSet = new Dictionary <string, object>(); requestObjectClaimSet.Add(OAuth2AndOIDCConst.iss, iss); // client_id requestObjectClaimSet.Add(OAuth2AndOIDCConst.aud, aud); // ROS EndPointのuri。 requestObjectClaimSet.Add(OAuth2AndOIDCConst.exp, exp); requestObjectClaimSet.Add(OAuth2AndOIDCConst.iat, CmnJwtToken.CreateIatClaim()); requestObjectClaimSet.Add(OAuth2AndOIDCConst.nbf, nbf); requestObjectClaimSet.Add(OAuth2AndOIDCConst.jti, CmnJwtToken.CreateJitClaim()); requestObjectClaimSet.Add(OAuth2AndOIDCConst.scope, scopes); requestObjectClaimSet.Add(OAuth2AndOIDCConst.client_notification_token, client_notification_token); requestObjectClaimSet.Add(OAuth2AndOIDCConst.binding_message, binding_message); if (!string.IsNullOrEmpty(user_code)) { requestObjectClaimSet.Add(OAuth2AndOIDCConst.user_code, user_code); } if (!string.IsNullOrEmpty(requested_expiry)) { requestObjectClaimSet.Add(OAuth2AndOIDCConst.requested_expiry, requested_expiry); } requestObjectClaimSet.Add(OAuth2AndOIDCConst.login_hint, login_hint); if (requestContextAndIntent != null) { foreach (string key in requestContextAndIntent.Keys) { requestObjectClaimSet.Add(key, requestContextAndIntent[key]); } } json = JsonConvert.SerializeObject(requestObjectClaimSet); #endregion #region JWT化 JWS_ES256_X509 jwtES256 = new JWS_ES256_X509(ecdsaX509FilePath, ecdsaX509Password); return(jwtES256.Create(json)); #endregion }
// AuthZに実装(パラメタ体系が違うため) #endregion #region Verify /// <summary>汎用認証サイトの発行したResponseObjectを検証する。</summary> /// <param name="response">string</param> /// <param name="jobj">out JObject</param> /// <returns>検証結果</returns> public static bool Verify(string response, out JObject jobj) { // JWS検証 string jwtPayload = ""; if (CmnJwtToken.Verify(response, out jwtPayload)) { jobj = ((JObject)JsonConvert.DeserializeObject(jwtPayload)); #region クレーム検証 if (jobj.ContainsKey(OAuth2AndOIDCConst.error)) { // errorの場合 return(true); } else { // errorでない場合 string iss = (string)jobj[OAuth2AndOIDCConst.iss]; string aud = (string)jobj[OAuth2AndOIDCConst.aud]; //string iat = (string)jobj[OAuth2AndOIDCConst.iat]; string exp = (string)jobj[OAuth2AndOIDCConst.exp]; long unixTimeSeconds = 0; #if NET45 unixTimeSeconds = PubCmnFunction.ToUnixTime(DateTimeOffset.Now); #else unixTimeSeconds = DateTimeOffset.Now.ToUnixTimeSeconds(); #endif if (iss == CmnClientParams.Isser && long.Parse(exp) >= unixTimeSeconds) { if (string.IsNullOrEmpty(OAuth2AndOIDCParams.JwkSetFilePath)) { // Client側 if (aud == OAuth2AndOIDCParams.ClientID) { // OAuth2 Clientバージョンの実装で成功 return(true); } else if (OAuth2AndOIDCParams.ClientIDs.Any(x => x == aud)) { // OAuth2 ResourcesServerバージョンの実装で成功 return(true); } else { // JWTの内容検証に失敗 } } else { // AuthZ側(検証用カバレッジ // OAuth2 AuthZバージョンの実装で成功 return(true); } } else { // JWTの内容検証に失敗 } } #endregion } else { // JWTの署名検証に失敗 jobj = null; } // 認証に失敗 return(false); }
// AuthZに実装(パラメタ体系が違うため) #endregion #region Verify /// <summary>汎用認証サイトの発行したIdTokenを検証する。</summary> /// <param name="id_token">string</param> /// <param name="access_token">string</param> /// <param name="code">string</param> /// <param name="state">string</param> /// <param name="sub">out string</param> /// <param name="nonce">out string</param> /// <param name="jobj">out JObject</param> /// <returns>検証結果</returns> public static bool Verify(string id_token, string access_token, string code, string state, out string sub, out string nonce, out JObject jobj) { sub = ""; nonce = ""; jobj = null; // JWS検証 string jwtPayload = ""; if (CmnJwtToken.Verify(id_token, out jwtPayload)) { jobj = ((JObject)JsonConvert.DeserializeObject(jwtPayload)); #region クレーム検証 // out sub = (string)jobj[OAuth2AndOIDCConst.sub]; nonce = (string)jobj[OAuth2AndOIDCConst.nonce]; string iss = (string)jobj[OAuth2AndOIDCConst.iss]; string aud = (string)jobj[OAuth2AndOIDCConst.aud]; //string iat = (string)jobj[OAuth2AndOIDCConst.iat]; string exp = (string)jobj[OAuth2AndOIDCConst.exp]; #region ハッシュ・クレーム検証 // at_hash string at_hash = (string)jobj[OAuth2AndOIDCConst.at_hash]; if (!string.IsNullOrEmpty(access_token) && !string.IsNullOrEmpty(at_hash)) { if (!IdToken.VerifyHash(access_token, at_hash)) { return(false); } } // c_hash string c_hash = (string)jobj[OAuth2AndOIDCConst.c_hash]; if (!string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(c_hash)) { if (!IdToken.VerifyHash(code, c_hash)) { return(false); } } // s_hash string s_hash = (string)jobj[OAuth2AndOIDCConst.s_hash]; if (!string.IsNullOrEmpty(state) && !string.IsNullOrEmpty(s_hash)) { if (!IdToken.VerifyHash(state, s_hash)) { return(false); } } #endregion long unixTimeSeconds = 0; #if NET45 unixTimeSeconds = PubCmnFunction.ToUnixTime(DateTimeOffset.Now); #else unixTimeSeconds = DateTimeOffset.Now.ToUnixTimeSeconds(); #endif if (iss == CmnClientParams.Isser && long.Parse(exp) >= unixTimeSeconds) { if (string.IsNullOrEmpty(OAuth2AndOIDCParams.JwkSetFilePath)) { // Client側 if (aud == OAuth2AndOIDCParams.ClientID) { // OAuth2 Clientバージョンの実装で成功 return(true); } else if (OAuth2AndOIDCParams.ClientIDs.Any(x => x == aud)) { // OAuth2 ResourcesServerバージョンの実装で成功 return(true); } else { // JWTの内容検証に失敗 } } else { // AuthZ側(検証用カバレッジ // OAuth2 AuthZバージョンの実装で成功 return(true); } } else { // JWTの内容検証に失敗 } #endregion } else { // JWTの署名検証に失敗 } // 認証に失敗 return(false); }
// AuthZに実装(パラメタ体系が違うため) #endregion #region Verify /// <summary>汎用認証サイトの発行したAccessTokenを検証する。</summary> /// <param name="access_token"> /// AccessTokenで以下の項目が必要 /// - iss /// - aud /// - iat /// - exp /// - sub /// - roles (option) /// - scopes (option) /// - その他 (option) /// </param> /// <param name="sub">out string</param> /// <param name="roles">out List(string)</param> /// <param name="scopes">out List(string)</param> /// <param name="jobj">out JObject</param> /// <returns>検証結果</returns> public static bool Verify(string access_token, out string sub, out List <string> roles, out List <string> scopes, out JObject jobj) { sub = ""; roles = new List <string>(); scopes = new List <string>(); jobj = null; // JWS検証 string jwtPayload = ""; if (CmnJwtToken.Verify(access_token, out jwtPayload)) { jobj = ((JObject)JsonConvert.DeserializeObject(jwtPayload)); #region クレーム検証 string iss = (string)jobj[OAuth2AndOIDCConst.iss]; string aud = (string)jobj[OAuth2AndOIDCConst.aud]; //string iat = (string)jobj[OAuth2AndOIDCConst.iat]; string exp = (string)jobj[OAuth2AndOIDCConst.exp]; sub = (string)jobj[OAuth2AndOIDCConst.sub]; if (jobj[OAuth2AndOIDCConst.Scope_Roles] != null) { roles = JsonConvert.DeserializeObject <List <string> >(jobj[OAuth2AndOIDCConst.Scope_Roles].ToString()); } if (jobj[OAuth2AndOIDCConst.scopes] != null) { scopes = JsonConvert.DeserializeObject <List <string> >(jobj[OAuth2AndOIDCConst.scopes].ToString()); } long unixTimeSeconds = 0; #if NET45 unixTimeSeconds = PubCmnFunction.ToUnixTime(DateTimeOffset.Now); #else unixTimeSeconds = DateTimeOffset.Now.ToUnixTimeSeconds(); #endif if (iss == CmnClientParams.Isser && long.Parse(exp) >= unixTimeSeconds) { if (string.IsNullOrEmpty(OAuth2AndOIDCParams.JwkSetFilePath)) { // Client側 if (aud == OAuth2AndOIDCParams.ClientID) { // OAuth2 Clientバージョンの実装で成功 return(true); } else if (OAuth2AndOIDCParams.ClientIDs.Any(x => x == aud)) { // OAuth2 ResourcesServerバージョンの実装で成功 return(true); } else { // JWTの内容検証に失敗 } } else { // AuthZ側(検証用カバレッジ // OAuth2 AuthZバージョンの実装で成功 return(true); } } else { // JWTの内容検証に失敗 } #endregion } else { // JWTの署名検証に失敗 } // 認証に失敗 return(false); }