//[Authorize] public Dictionary <string, string> IntrospectToken(FormDataCollection formData) { // 戻り値 // ・正常 Dictionary <string, string> ret = new Dictionary <string, string>(); // ・異常 Dictionary <string, string> err = new Dictionary <string, string>(); // 変数 string[] temp = null; string token = formData[OAuth2AndOIDCConst.token]; string token_type_hint = formData[OAuth2AndOIDCConst.token_type_hint]; // クライアント認証 // クライアント識別子 string authHeader = HttpContext.Current.Request.Headers[OAuth2AndOIDCConst.HttpHeader_Authorization]; temp = authHeader.Split(' '); if (temp[0] == OAuth2AndOIDCConst.Basic) { temp = CustomEncode.ByteToString( CustomEncode.FromBase64String(temp[1]), CustomEncode.us_ascii).Split(':'); string clientId = temp[0]; string clientSecret = temp[1]; if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(clientId)) { // 検証完了 AuthenticationTicket ticket = null; if (token_type_hint == OAuth2AndOIDCConst.AccessToken) { // 検証 AccessTokenFormatJwt verifier = new AccessTokenFormatJwt(); ticket = verifier.Unprotect(token); if (ticket == null) { // 検証失敗 // 検証エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid token"); } else { // 検証成功 // メタデータの返却 ret.Add("active", "true"); ret.Add(OAuth2AndOIDCConst.token_type, token_type_hint); string scopes = ""; foreach (Claim claim in ticket.Identity.Claims) { if (claim.Type.StartsWith(OAuth2AndOIDCConst.Claim_Base)) { if (claim.Type == OAuth2AndOIDCConst.Claim_Scopes) { scopes += claim.Value + " "; } else { ret.Add(claim.Type.Substring( OAuth2AndOIDCConst.Claim_Base.Length), claim.Value); } } } ret.Add(OAuth2AndOIDCConst.Claim_Scopes.Substring( OAuth2AndOIDCConst.Claim_Base.Length), scopes.Trim()); return(ret); // 成功 } } else if (token_type_hint == OAuth2AndOIDCConst.RefreshToken) { // refresh_token参照 ticket = RefreshTokenProvider.ReferDirectly(token); if (ticket == null) { // 検証失敗 // 検証エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid token"); } else { // 検証成功 // メタデータの返却 ret.Add("active", "true"); ret.Add(OAuth2AndOIDCConst.token_type, token_type_hint); string scopes = ""; foreach (Claim claim in ticket.Identity.Claims) { if (claim.Type.StartsWith(OAuth2AndOIDCConst.Claim_Base)) { if (claim.Type == OAuth2AndOIDCConst.Claim_Scopes) { scopes += claim.Value + " "; } else { ret.Add(claim.Type.Substring( OAuth2AndOIDCConst.Claim_Base.Length), claim.Value); } } } ret.Add(OAuth2AndOIDCConst.Claim_Scopes.Substring( OAuth2AndOIDCConst.Claim_Base.Length), scopes.Trim()); return(ret); // 成功 } } else { // token_type_hint パラメタ・エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid token_type_hint"); } } else { // クライアント認証エラー(Credential不正 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 { // クライアント認証エラー(ヘッダ不正 err.Add("error", "invalid_request"); err.Add("error_description", "Invalid authentication header"); } return(err); // 失敗 }
//[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); // 失敗 }
//[Authorize] public Dictionary <string, string> RevokeToken(FormDataCollection formData) { // 戻り値(エラー) Dictionary <string, string> err = new Dictionary <string, string>(); // 変数 string[] temp = null; string token = formData[OAuth2AndOIDCConst.token]; string token_type_hint = formData[OAuth2AndOIDCConst.token_type_hint]; // クライアント認証 // クライアント識別子 string authHeader = HttpContext.Current.Request.Headers[OAuth2AndOIDCConst.HttpHeader_Authorization]; temp = authHeader.Split(' '); if (temp[0] == OAuth2AndOIDCConst.Basic) { temp = CustomEncode.ByteToString( CustomEncode.FromBase64String(temp[1]), CustomEncode.us_ascii).Split(':'); string clientId = temp[0]; string clientSecret = temp[1]; if (!(string.IsNullOrEmpty(clientId) && string.IsNullOrEmpty(clientSecret))) { // *.config or OAuth2Dataテーブルを参照してクライアント認証を行なう。 if (clientSecret == OAuth2Helper.GetInstance().GetClientSecret(clientId)) { // 検証完了 if (token_type_hint == OAuth2AndOIDCConst.AccessToken) { // 検証 AccessTokenFormatJwt verifier = new AccessTokenFormatJwt(); AuthenticationTicket ticket = verifier.Unprotect(token); if (ticket == null) { // 検証失敗 // 検証エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid token"); } else { // 検証成功 // jtiの取り出し Claim jti = ticket.Identity.Claims.Where( x => x.Type == OAuth2AndOIDCConst.Claim_JwtId).FirstOrDefault <Claim>(); // access_token取消 OAuth2RevocationProvider.GetInstance().Create(jti.Value); return(null); // 成功 } } else if (token_type_hint == OAuth2AndOIDCConst.RefreshToken) { // refresh_token取消 if (RefreshTokenProvider.DeleteDirectly(token)) { // 取り消し成功 return(null); // 成功 } else { // 取り消し失敗 err.Add("error", "invalid_request"); err.Add("error_description", "invalid token"); } } else { // token_type_hint パラメタ・エラー err.Add("error", "invalid_request"); err.Add("error_description", "invalid token_type_hint"); } } else { // クライアント認証エラー(Credential不正 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 { // クライアント認証エラー(ヘッダ不正 err.Add("error", "invalid_request"); err.Add("error_description", "Invalid authentication header"); } return(err); // 失敗 }