Ejemplo n.º 1
0
        /// <summary>ChangeToIdTokenFromJwt</summary>
        /// <param name="access_token">Jwt (string)</param>
        /// <returns>IdToken (string)</returns>
        public static string ChangeToIdTokenFromJwt(string access_token)
        {
            if (access_token.Contains("."))
            {
                string[] temp = access_token.Split('.');
                string   json = CustomEncode.ByteToString(CustomEncode.FromBase64UrlString(temp[1]), CustomEncode.UTF_8);
                Dictionary <string, object> authTokenClaimSet = JsonConvert.DeserializeObject <Dictionary <string, object> >(json);

                // ・access_tokenがJWTで、payloadに"nonce" and "scope=openidクレームが存在する場合、
                if (authTokenClaimSet.ContainsKey("nonce") &&
                    authTokenClaimSet.ContainsKey("scopes"))
                {
                    JArray scopes = (JArray)authTokenClaimSet["scopes"];

                    // ・OpenID Connect : response_type=codeに対応する。
                    if (scopes.Any(x => x.ToString() == ASPNETIdentityConst.Scope_Openid))
                    {
                        //・payloadからscopeを削除する。
                        authTokenClaimSet.Remove("scopes");
                        //・編集したpayloadを再度JWTとして署名する。
                        string    newPayload = JsonConvert.SerializeObject(authTokenClaimSet);
                        JWT_RS256 jwtRS256   = null;

                        // 署名
                        jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_pfx, ASPNETIdentityConfig.OAuthJWTPassword,
                                                 X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                        string id_token = jwtRS256.Create(newPayload);

                        // 検証
                        jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_cer, ASPNETIdentityConfig.OAuthJWTPassword,
                                                 X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

                        if (jwtRS256.Verify(id_token))
                        {
                            // 検証できた。
                            return(id_token);
                        }
                        else
                        {
                            // 検証できなかった。
                        }
                    }
                    else
                    {
                        // OIDCでない。
                    }
                }
                else
                {
                    // OIDCでない。
                }
            }
            else
            {
                // JWTでない。
            }

            return("");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// ProtectFromPayload
        ///   Hybrid Flow対応(access_token_payloadを処理)
        /// </summary>
        /// <param name="access_token_payload">AccessTokenのPayload</param>
        /// <param name="customExp">Hybrid Flowのtokenに対応したexp</param>
        /// <returns></returns>
        public static string ProtectFromPayload(string access_token_payload, ulong customExp)
        {
            string json = "";
            string jwt  = "";

            // ticketの値を使用(これは、codeのexpっぽい。300秒になっているのでNG。)
            //authTokenClaimSet.Add("exp", ticket.Properties.ExpiresUtc.Value.ToUnixTimeSeconds().ToString());
            //authTokenClaimSet.Add("exp", DateTimeOffset.Now.AddSeconds(customExp).ToUnixTimeSeconds().ToString());

            #region JSON編集

            // access_token_payloadのDictionary化
            Dictionary <string, object> dic =
                JsonConvert.DeserializeObject <Dictionary <string, object> >(access_token_payload);

            // ★ customExpの値を使用する。
            dic["exp"] = DateTimeOffset.Now.AddSeconds(customExp).ToUnixTimeSeconds().ToString();
            // ★ Hybrid Flow対応なので、scopeを制限してもイイ。
            dic["scopes"] = dic["scopes"];

            json = JsonConvert.SerializeObject(dic);

            #endregion

            #region JWT化

            JWT_RS256 jwtRS256 = null;

            // 署名
            jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_pfx, ASPNETIdentityConfig.OAuthJWTPassword,
                                     X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            jwt = jwtRS256.Create(json);

            // 検証
            jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_cer, ASPNETIdentityConfig.OAuthJWTPassword,
                                     X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            if (jwtRS256.Verify(jwt))
            {
                return(jwt); // 検証できた。
            }
            else
            {
                return(""); // 検証できなかった。
            }

            #endregion
        }
Ejemplo n.º 3
0
        /// <summary>JWT生成</summary>
        private void btnJWTSign_Click(object sender, EventArgs e)
        {
            if (rbnJWTHS256.Checked)
            {
                // HS256
                string    password = GetPassword.Generate(20, 10);
                JWT_HS256 jwtHS256 = new JWT_HS256(CustomEncode.StringToByte(password, CustomEncode.UTF_8));

                // 生成
                string jwt = jwtHS256.Create(this.txtJWTPayload.Text);

                // 出力
                this.txtJWTKey.Text  = password;
                this.txtJWTJWK.Text  = jwtHS256.JWK;
                this.txtJWTSign.Text = jwt;

                // 改竄可能なフィールドに出力
                string[] temp = jwt.Split('.');
                this.txtJWTHeader.Text = CustomEncode.ByteToString(
                    CustomEncode.FromBase64UrlString(temp[0]), CustomEncode.UTF_8);
                this.txtJWTPayload.Text = CustomEncode.ByteToString(
                    CustomEncode.FromBase64UrlString(temp[1]), CustomEncode.UTF_8);
            }
            else
            {
                // RS256 (X509Cer)
                JWT_RS256 jwtRS256 = new JWT_RS256(this.CertificateFilePath_pfx, this.CertificateFilePassword);

                // 生成
                string jwt = jwtRS256.Create(this.txtJWTPayload.Text);

                // 出力
                this.txtJWTSign.Text = jwt;

                // 改竄可能なフィールドに出力
                string[] temp = jwt.Split('.');
                this.txtJWTHeader.Text = CustomEncode.ByteToString(
                    CustomEncode.FromBase64UrlString(temp[0]), CustomEncode.UTF_8);
                this.txtJWTPayload.Text = CustomEncode.ByteToString(
                    CustomEncode.FromBase64UrlString(temp[1]), CustomEncode.UTF_8);
            }
        }
Ejemplo n.º 4
0
        /// <summary>Protect</summary>
        /// <param name="ticket">AuthenticationTicket</param>
        /// <returns>JWT文字列</returns>
        public string Protect(AuthenticationTicket ticket)
        {
            string json = "";
            string jwt  = "";

            // チェック
            if (ticket == null)
            {
                throw new ArgumentNullException("ticket");
            }

            ApplicationUserManager userManager
                = HttpContext.Current.GetOwinContext().GetUserManager <ApplicationUserManager>();
            ApplicationUser user = userManager.FindByName(ticket.Identity.Name); // 同期版でOK。

            #region ClaimSetの生成

            Dictionary <string, object> authTokenClaimSet = new Dictionary <string, object>();
            List <string> scopes = new List <string>();
            List <string> roles  = new List <string>();

            foreach (Claim c in ticket.Identity.Claims)
            {
                if (c.Type == ASPNETIdentityConst.Claim_Issuer)
                {
                    authTokenClaimSet.Add("iss", c.Value);
                }
                else if (c.Type == ASPNETIdentityConst.Claim_Audience)
                {
                    authTokenClaimSet.Add("aud", c.Value);
                }
                else if (c.Type == ASPNETIdentityConst.Claim_Nonce)
                {
                    authTokenClaimSet.Add("nonce", c.Value);
                }
                else if (c.Type == ASPNETIdentityConst.Claim_Scope)
                {
                    scopes.Add(c.Value);
                }
                else if (c.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role")
                {
                    roles.Add(c.Value);
                }
            }

            authTokenClaimSet.Add("sub", ticket.Identity.Name);
            authTokenClaimSet.Add("iat", ticket.Properties.IssuedUtc.Value.ToUnixTimeSeconds().ToString());
            authTokenClaimSet.Add("exp", ticket.Properties.ExpiresUtc.Value.ToUnixTimeSeconds().ToString());

            // scope値によって、返す値を変更する。
            foreach (string scope in scopes)
            {
                switch (scope.ToLower())
                {
                    #region OpenID Connect
                case ASPNETIdentityConst.Scope_Profile:
                    // ・・・
                    break;

                case ASPNETIdentityConst.Scope_Email:
                    authTokenClaimSet.Add("email", user.Email);
                    authTokenClaimSet.Add("email_verified", user.EmailConfirmed.ToString());
                    break;

                case ASPNETIdentityConst.Scope_Phone:
                    authTokenClaimSet.Add("phone_number", user.PhoneNumber);
                    authTokenClaimSet.Add("phone_number_verified", user.PhoneNumberConfirmed.ToString());
                    break;

                case ASPNETIdentityConst.Scope_Address:
                    // ・・・
                    break;
                    #endregion

                    #region Else

                case ASPNETIdentityConst.Scope_Userid:
                    authTokenClaimSet.Add(ASPNETIdentityConst.Scope_Userid, user.Id);
                    break;

                case ASPNETIdentityConst.Scope_Roles:
                    authTokenClaimSet.Add(ASPNETIdentityConst.Scope_Roles, roles);
                    break;

                    #endregion
                }
            }

            authTokenClaimSet.Add("scopes", scopes);

            json = JsonConvert.SerializeObject(authTokenClaimSet);

            #endregion

            #region JWT化

            JWT_RS256 jwtRS256 = null;

            // 署名
            jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_pfx, ASPNETIdentityConfig.OAuthJWTPassword,
                                     X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            jwt = jwtRS256.Create(json);

            // 検証
            jwtRS256 = new JWT_RS256(ASPNETIdentityConfig.OAuthJWT_cer, ASPNETIdentityConfig.OAuthJWTPassword,
                                     X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            if (jwtRS256.Verify(jwt))
            {
                return(jwt); // 検証できた。
            }
            else
            {
                return(""); // 検証できなかった。
            }

            #endregion
        }