static void Main(string[] args) { string iss = OAuth2AndOIDCParams.Isser; string aud = OAuth2AndOIDCParams.Audience; string scopes = "hoge1 hoge2 hoge3"; JObject jobj = null; JWS_RS256_XML jws_RS256 = new JWS_RS256_XML(); Console.WriteLine("PrivateKey:"); Console.WriteLine(CustomEncode.ToBase64String( CustomEncode.StringToByte(jws_RS256.XMLPrivateKey, CustomEncode.us_ascii))); Console.WriteLine(""); Console.WriteLine("PublicKey:"); Console.WriteLine(CustomEncode.ToBase64String( CustomEncode.StringToByte(jws_RS256.XMLPublicKey, CustomEncode.us_ascii))); Console.WriteLine(""); string jwtAssertion = JwtAssertion.CreateJwtBearerTokenFlowAssertion( OAuth2AndOIDCParams.Isser, OAuth2AndOIDCParams.Audience, new System.TimeSpan(0, 30, 0), scopes, jws_RS256.XMLPrivateKey); if (JwtAssertion.VerifyJwtBearerTokenFlowAssertion( jwtAssertion, out iss, out aud, out scopes, out jobj, jws_RS256.XMLPublicKey)) { if (iss == OAuth2AndOIDCParams.Isser && aud == OAuth2AndOIDCParams.Audience) { Console.WriteLine("JwtAssertion:"); Console.WriteLine(jwtAssertion); Console.WriteLine(""); Console.ReadLine(); return; } } Console.WriteLine("Error"); Console.ReadLine(); }
static void Main(string[] args) { string iss = GetConfigParameter.GetConfigValue("iss"); string aud = GetConfigParameter.GetConfigValue("aud"); string scopes = "hoge1 hoge2 hoge3"; JObject jobj = null; JWT_RS256_XML jwt_RS256 = new JWT_RS256_XML(); Console.WriteLine("PrivateKey:"); Console.WriteLine(CustomEncode.ToBase64String( CustomEncode.StringToByte(jwt_RS256.XMLPrivateKey, CustomEncode.us_ascii))); Console.WriteLine(""); Console.WriteLine("PublicKey:"); Console.WriteLine(CustomEncode.ToBase64String( CustomEncode.StringToByte(jwt_RS256.XMLPublicKey, CustomEncode.us_ascii))); Console.WriteLine(""); string jwtAssertion = JwtAssertion.CreateJwtBearerTokenFlowAssertion( GetConfigParameter.GetConfigValue("iss"), GetConfigParameter.GetConfigValue("aud"), new System.TimeSpan(0, 30, 0), scopes, jwt_RS256.XMLPrivateKey); if (JwtAssertion.VerifyJwtBearerTokenFlowAssertion( jwtAssertion, out iss, out aud, out scopes, out jobj, jwt_RS256.XMLPublicKey)) { if (iss == GetConfigParameter.GetConfigValue("iss") && aud == GetConfigParameter.GetConfigValue("aud")) { Console.WriteLine("JwtAssertion:"); Console.WriteLine(jwtAssertion); Console.WriteLine(""); Console.ReadLine(); return; } } Console.WriteLine("Error"); Console.ReadLine(); }
public async Task <ActionResult> TestJWTBearerTokenFlow() { // Token2エンドポイントにアクセス string aud = ASPNETIdentityConfig.OAuth2AuthorizationServerEndpointsRootURI + ASPNETIdentityConfig.OAuth2BearerTokenEndpoint2; // ClientNameから、client_id(iss)を取得。 string iss = ""; if (User.Identity.IsAuthenticated) { // User Accountの場合、 iss = OAuth2Helper.GetInstance().GetClientIdByName(User.Identity.Name); } else { // Client Accountの場合、 iss = OAuth2Helper.GetInstance().GetClientIdByName("TestClient"); } // テストなので秘密鍵は共通とする。 string privateKey = OAuth2AndOIDCParams.OAuth2JwtAssertionPrivatekey; privateKey = CustomEncode.ByteToString(CustomEncode.FromBase64String(privateKey), CustomEncode.us_ascii); string response = await OAuth2Helper.GetInstance() .JwtBearerTokenFlowAsync(new Uri( ASPNETIdentityConfig.OAuth2AuthorizationServerEndpointsRootURI + ASPNETIdentityConfig.OAuth2BearerTokenEndpoint2), JwtAssertion.CreateJwtBearerTokenFlowAssertion( iss, aud, new TimeSpan(0, 0, 30), ASPNETIdentityConst.StandardScopes, privateKey)); ViewBag.Response = response; ViewBag.AccessToken = ((JObject)JsonConvert.DeserializeObject(response))[OAuth2AndOIDCConst.AccessToken]; return(View("OAuth2ClientAuthenticationFlow")); }
//[Authorize] public Dictionary <string, string> OAuth2BearerToken2(FormDataCollection formData) { // 戻り値 // ・正常 Dictionary <string, string> ret = new Dictionary <string, string>(); // ・異常 Dictionary <string, string> err = new Dictionary <string, string>(); // 変数 string grant_type = formData[OAuth2AndOIDCConst.grant_type]; string assertion = formData[OAuth2AndOIDCConst.assertion]; // クライアント認証 if (grant_type == OAuth2AndOIDCConst.JwtBearerTokenFlowGrantType) { Dictionary <string, string> dic = JsonConvert.DeserializeObject <Dictionary <string, string> >( CustomEncode.ByteToString(CustomEncode.FromBase64UrlString( assertion.Split('.')[1]), CustomEncode.us_ascii)); string pubKey = OAuth2Helper.GetInstance().GetJwtAssertionPublickey(dic[OAuth2AndOIDCConst.iss]); pubKey = CustomEncode.ByteToString(CustomEncode.FromBase64String(pubKey), CustomEncode.us_ascii); if (!string.IsNullOrEmpty(pubKey)) { string iss = ""; string aud = ""; string scopes = ""; JObject jobj = null; if (JwtAssertion.VerifyJwtBearerTokenFlowAssertion(assertion, out iss, out aud, out scopes, out jobj, pubKey)) { // aud 検証 if (aud == ASPNETIdentityConfig.OAuth2AuthorizationServerEndpointsRootURI + ASPNETIdentityConfig.OAuth2BearerTokenEndpoint2) { // ここからは、JwtAssertionではなく、JwtTokenを作るので、属性設定に注意。 ClaimsIdentity identity = OAuth2Helper.AddClaim( new ClaimsIdentity(OAuthDefaults.AuthenticationType), iss, "", scopes.Split(' '), ""); AuthenticationProperties prop = new AuthenticationProperties(); prop.IssuedUtc = DateTimeOffset.UtcNow; prop.ExpiresUtc = DateTimeOffset.Now.Add(ASPNETIdentityConfig.OAuth2AccessTokenExpireTimeSpanFromMinutes); // token_type ret.Add(OAuth2AndOIDCConst.token_type, OAuth2AndOIDCConst.Bearer.ToLower()); // access_token AccessTokenFormatJwt verifier = new AccessTokenFormatJwt(); string access_token = verifier.Protect(new AuthenticationTicket(identity, prop)); ret.Add(OAuth2AndOIDCConst.AccessToken, access_token); // expires_in jobj = (JObject)JsonConvert.DeserializeObject( CustomEncode.ByteToString(CustomEncode.FromBase64UrlString( access_token.Split('.')[1]), CustomEncode.us_ascii)); ret.Add("expires_in", (long.Parse((string)jobj[OAuth2AndOIDCConst.exp]) - long.Parse((string)jobj[OAuth2AndOIDCConst.iat])).ToString()); // オペレーション・トレース・ログ出力 string clientName = OAuth2Helper.GetInstance().GetClientName(iss); Logging.MyOperationTrace(string.Format( "{0}({1}) passed the 'jwt bearer token flow' by {2}({3}).", iss, clientName, iss, clientName)); return(ret); // 成功 } else { // クライアント認証エラー(Credential(aud)不正 err.Add("error", "invalid_client"); err.Add("error_description", "Invalid credential"); } } else { // クライアント認証エラー(Credential(署名)不正 err.Add("error", "invalid_client"); err.Add("error_description", "Invalid credential"); } } else { // クライアント認証エラー(Credential(iss or pubKey)不正 err.Add("error", "invalid_client"); err.Add("error_description", "Invalid credential"); } } else { // grant_type パラメタ・エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid grant_type"); } return(err); // 失敗 }
/// <summary> /// Authorization Code、Resource Owner Password Credentialsl、Client Credentialsグラント種別において、 /// OAuthBearerTokenEndpointPathを処理する場合に発生する、" クライアント認証 " を行なうメソッド。 /// " クライアント認証 "では、以下の両方の要素を検証する。 /// ・context.ClientId が、登録された "client_id" であること。 /// ・その他、資格情報が要求に存在していることを検証する。 /// </summary> /// <param name="context">OAuthValidateClientAuthenticationContext</param> /// <returns>Task</returns> /// <see cref="https://msdn.microsoft.com/ja-jp/library/dn385497.aspx"/> public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { // クライアント識別子 string clientId = ""; string clientSecret = ""; // ・context.Validated を呼び出し、contextを検証完了に設定する。 // ・検証完了にしなければ要求はそれ以上先には進まない。 //context.Validated(clientId); #region クライアント認証を行なう。 if (string.IsNullOrEmpty(context.Parameters[OAuth2AndOIDCConst.grant_type])) { // 指定なし。 // 検証未完 } else if (context.Parameters[OAuth2AndOIDCConst.grant_type].ToLower() == OAuth2AndOIDCConst.AuthorizationCodeGrantType) { #region Authorization Codeグラント種別 // "client_id" および "client_secret"を基本認証の認証ヘッダから取得 if (context.TryGetBasicCredentials(out clientId, out clientSecret)) { // 通常のクライアント認証 if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(context.ClientId)) { // 検証完了 context.Validated(clientId); } } } else { // その他のクライアント認証の可能性 string assertion = context.Parameters.Get(OAuth2AndOIDCConst.assertion); if (!string.IsNullOrEmpty(assertion)) { // JWT client assertion Dictionary <string, string> dic = JsonConvert.DeserializeObject <Dictionary <string, string> >( CustomEncode.ByteToString(CustomEncode.FromBase64UrlString( assertion.Split('.')[1]), CustomEncode.us_ascii)); string pubKey = OAuth2Helper.GetInstance().GetJwtAssertionPublickey(dic[OAuth2AndOIDCConst.iss]); pubKey = CustomEncode.ByteToString(CustomEncode.FromBase64String(pubKey), CustomEncode.us_ascii); if (!string.IsNullOrEmpty(pubKey)) { string iss = ""; string aud = ""; string scopes = ""; JObject jobj = null; if (JwtAssertion.VerifyJwtBearerTokenFlowAssertion( assertion, out iss, out aud, out scopes, out jobj, pubKey)) { // aud 検証 if (aud == ASPNETIdentityConfig.OAuth2AuthorizationServerEndpointsRootURI + ASPNETIdentityConfig.OAuth2BearerTokenEndpoint) { // 検証完了 context.Validated(iss); } } } } else { // クライアント認証なしエラー } } #endregion } else if (context.Parameters[OAuth2AndOIDCConst.grant_type].ToLower() == OAuth2AndOIDCConst.ResourceOwnerPasswordCredentialsGrantType) { #region Resource Owner Password Credentialsグラント種別 #region 参考 // Simple OAuth Server: Implementing a Simple OAuth Server with Katana // OAuth Authorization Server Components (Part 1) - Tugberk Ugurlu's Blog // http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part-1 // ・・・ 基本認証を使用する既存のクライアントを認証してOAuthに移行する。 #endregion // "client_id" および "client_secret"を基本認証の認証ヘッダから取得 if (context.TryGetBasicCredentials(out clientId, out clientSecret)) { if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(context.ClientId)) { // 検証完了 context.Validated(clientId); } } } #endregion } else if (context.Parameters[OAuth2AndOIDCConst.grant_type].ToLower() == OAuth2AndOIDCConst.ClientCredentialsGrantType) { #region Client Credentialsグラント種別 // "client_id" および "client_secret"を基本認証の認証ヘッダから取得 if (context.TryGetBasicCredentials(out clientId, out clientSecret)) { if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(context.ClientId)) { // 検証完了 context.Validated(clientId); } } } #endregion } else if (context.Parameters[OAuth2AndOIDCConst.grant_type].ToLower() == OAuth2AndOIDCConst.RefreshTokenGrantType) { #region RefreshToken if (!ASPNETIdentityConfig.EnableRefreshToken) { throw new NotSupportedException(Resources.ApplicationOAuthBearerTokenProvider.EnableRefreshToken); } // "client_id" および "client_secret"を基本認証の認証ヘッダから取得 if (context.TryGetBasicCredentials(out clientId, out clientSecret)) { if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(context.ClientId)) { // 検証完了 context.Validated(clientId); } } } #endregion } else { // 不明な値 // 検証未完 } #endregion // 結果を返す。 return(Task.FromResult(0)); }