সি # তে কি কোনও জেএসএন ওয়েব টোকেন (জেডাব্লুটি) উদাহরণ রয়েছে?


101

আমার মনে হচ্ছে আমি এখানে পাগল বড়ি নিচ্ছি। সাধারণত কোনও নির্দিষ্ট কাজের জন্য সর্বদা মিলিয়ন লাইব্রেরি এবং ওয়েবের চারপাশে স্যাম্পল রয়েছে। আমি এখানে বর্ণিত জেএসএন ওয়েব টোকেন (জেডাব্লুটি) ব্যবহার করে একটি গুগল "পরিষেবা অ্যাকাউন্ট" দিয়ে প্রমাণীকরণ প্রয়োগ করার চেষ্টা করছি ।

তবে পিএইচপি, পাইথন এবং জাভাতে কেবল ক্লায়েন্ট লাইব্রেরি রয়েছে। এমনকি গুগলের প্রমাণীকরণের বাইরে জেডাব্লুটি উদাহরণগুলি অনুসন্ধান করা, জেডাব্লুটি ধারণাটিতে কেবল ক্রিকেট এবং খসড়া রয়েছে। এটি কি আসলেই নতুন এবং সম্ভবত একটি গুগল মালিকানাধীন সিস্টেম?

জাভা নমুনা যা আমি ব্যাখ্যা করতে পরিচালনা করতে পারতাম এটি সবচেয়ে নিবিড় এবং ভয়ঙ্কর দেখাচ্ছে। সি # তে কিছু একটা আছে যা আমি কমপক্ষে শুরু করতে পারি। এর সাথে কোনও সহায়তা দুর্দান্ত হবে!


2
পিটার আপনার উত্তর আছে। জেডাব্লুটিটি একটি তুলনামূলকভাবে নতুন টোকেন ফর্ম্যাট, এজন্য নমুনাগুলি আসতে এখনও কিছুটা কঠিন, তবে এটি খুব দ্রুত বাড়ছে কারণ জেডব্লিউটি এসডাব্লুটিটির জন্য খুব প্রয়োজনীয় প্রতিস্থাপন are মাইক্রোসফ্ট টোকেন ফর্ম্যাটটিকে সমর্থন করছে, উদাহরণস্বরূপ লাইভ কানেক্ট এপিআই জেডাব্লুটি ব্যবহার করে।
অ্যান্ড্রু ল্যাভারস

অ্যাপ ইঞ্জিনের সাথে কি এর কোনও যোগসূত্র রয়েছে?
নিক জনসন

উত্তর:


74

ধন্যবাদ সবাইকে. আমি একটি জসন ওয়েব টোকনের একটি বেস বাস্তবায়ন পেয়েছি এবং এটিতে গুগলের স্বাদে প্রসারিত করেছি। আমি এখনও এটি সম্পূর্ণরূপে কাজ করতে পেলাম না তবে এটি সেখানে 97%। এই প্রকল্পটি তার বাষ্পটি হারিয়েছে, সুতরাং আশা করি এটি অন্য কাউকে একটি ভাল শুরুর দিকে সহায়তা করবে:

দ্রষ্টব্য: আমি বেস বাস্তবায়নে যে পরিবর্তনগুলি করেছি (এটি কোথায় পেয়েছি তা মনে করতে পারি না) হ'ল:

  1. এইচএস 256 -> আরএস 256 পরিবর্তন করা হয়েছে
  2. শিরোনামে জেডাব্লুটিটি এবং অলগ ক্রমটি অদলবদল করে। গুগল বা অনুমানটি কে এটি ভুল করেছে তা নিশ্চিত নন, তবে গুগল এটিকে সেভাবে নেয় যা তাদের ডক্স অনুসারে এটি নীচে রয়েছে।
public enum JwtHashAlgorithm
{
    RS256,
    HS384,
    HS512
}

public class JsonWebToken
{
    private static Dictionary<JwtHashAlgorithm, Func<byte[], byte[], byte[]>> HashAlgorithms;

    static JsonWebToken()
    {
        HashAlgorithms = new Dictionary<JwtHashAlgorithm, Func<byte[], byte[], byte[]>>
            {
                { JwtHashAlgorithm.RS256, (key, value) => { using (var sha = new HMACSHA256(key)) { return sha.ComputeHash(value); } } },
                { JwtHashAlgorithm.HS384, (key, value) => { using (var sha = new HMACSHA384(key)) { return sha.ComputeHash(value); } } },
                { JwtHashAlgorithm.HS512, (key, value) => { using (var sha = new HMACSHA512(key)) { return sha.ComputeHash(value); } } }
            };
    }

    public static string Encode(object payload, string key, JwtHashAlgorithm algorithm)
    {
        return Encode(payload, Encoding.UTF8.GetBytes(key), algorithm);
    }

    public static string Encode(object payload, byte[] keyBytes, JwtHashAlgorithm algorithm)
    {
        var segments = new List<string>();
        var header = new { alg = algorithm.ToString(), typ = "JWT" };

        byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
        byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
        //byte[] payloadBytes = Encoding.UTF8.GetBytes(@"{"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com","scope":"https://www.googleapis.com/auth/prediction","aud":"https://accounts.google.com/o/oauth2/token","exp":1328554385,"iat":1328550785}");

        segments.Add(Base64UrlEncode(headerBytes));
        segments.Add(Base64UrlEncode(payloadBytes));

        var stringToSign = string.Join(".", segments.ToArray());

        var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);

        byte[] signature = HashAlgorithms[algorithm](keyBytes, bytesToSign);
        segments.Add(Base64UrlEncode(signature));

        return string.Join(".", segments.ToArray());
    }

    public static string Decode(string token, string key)
    {
        return Decode(token, key, true);
    }

    public static string Decode(string token, string key, bool verify)
    {
        var parts = token.Split('.');
        var header = parts[0];
        var payload = parts[1];
        byte[] crypto = Base64UrlDecode(parts[2]);

        var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
        var headerData = JObject.Parse(headerJson);
        var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
        var payloadData = JObject.Parse(payloadJson);

        if (verify)
        {
            var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
            var keyBytes = Encoding.UTF8.GetBytes(key);
            var algorithm = (string)headerData["alg"];

            var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign);
            var decodedCrypto = Convert.ToBase64String(crypto);
            var decodedSignature = Convert.ToBase64String(signature);

            if (decodedCrypto != decodedSignature)
            {
                throw new ApplicationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature));
            }
        }

        return payloadData.ToString();
    }

    private static JwtHashAlgorithm GetHashAlgorithm(string algorithm)
    {
        switch (algorithm)
        {
            case "RS256": return JwtHashAlgorithm.RS256;
            case "HS384": return JwtHashAlgorithm.HS384;
            case "HS512": return JwtHashAlgorithm.HS512;
            default: throw new InvalidOperationException("Algorithm not supported.");
        }
    }

    // from JWT spec
    private static string Base64UrlEncode(byte[] input)
    {
        var output = Convert.ToBase64String(input);
        output = output.Split('=')[0]; // Remove any trailing '='s
        output = output.Replace('+', '-'); // 62nd char of encoding
        output = output.Replace('/', '_'); // 63rd char of encoding
        return output;
    }

    // from JWT spec
    private static byte[] Base64UrlDecode(string input)
    {
        var output = input;
        output = output.Replace('-', '+'); // 62nd char of encoding
        output = output.Replace('_', '/'); // 63rd char of encoding
        switch (output.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: output += "=="; break; // Two pad chars
            case 3: output += "="; break; // One pad char
            default: throw new System.Exception("Illegal base64url string!");
        }
        var converted = Convert.FromBase64String(output); // Standard base64 decoder
        return converted;
    }
}

এবং তারপরে আমার গুগল নির্দিষ্ট জেডাব্লুটি ক্লাস:

public class GoogleJsonWebToken
{
    public static string Encode(string email, string certificateFilePath)
    {
        var utc0 = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
        var issueTime = DateTime.Now;

        var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
        var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour, but lets play on safe side

        var payload = new
        {
            iss = email,
            scope = "https://www.googleapis.com/auth/gan.readonly",
            aud = "https://accounts.google.com/o/oauth2/token",
            exp = exp,
            iat = iat
        };

        var certificate = new X509Certificate2(certificateFilePath, "notasecret");

        var privateKey = certificate.Export(X509ContentType.Cert);

        return JsonWebToken.Encode(payload, privateKey, JwtHashAlgorithm.RS256);
    }
}

9
আসল বাস্তবায়নটি জন শিহানস জেডাব্লুটি লাইব্রেরি বলে মনে হচ্ছে: github.com/johnsheehan/jwt
Torbjørn

দেখে মনে হচ্ছে জন হ'ল আরএস এনক্রিপশন অ্যালগরিদমগুলি (আলগ পতাকা) সমর্থন করে না তবে এই সংস্করণটি তা করে।
রায়ান

15
এই সংস্করণটি আরএস 256 স্বাক্ষরকারী অ্যালগরিদমকে সঠিকভাবে সমর্থন করে না! এটি কেবল কী বাইটগুলির সাথে ইনপুটটি হ্যাশটিকে সঠিকভাবে এনক্রিপ্ট করার পরিবর্তে গোপন হিসাবে পিকেআই-তে করা উচিত as এটি যথাযথ বাস্তবায়ন ব্যতীত আরএস 256 লেবেলের জন্য কেবল এইচএস 256 লেবেলটি স্যুইচ করে।
হ্যান্স জেড।

1
উপরোক্ত কোডটি আংশিকভাবে তাকে বর্ণিত সুরক্ষা হামলার সাপেক্ষে: auth0.com/blog/2015/03/31/… এটি ঝুঁকিপূর্ণ "যদি কোনও সার্ভার আরএসএর সাথে স্বাক্ষরিত একটি টোকেনের প্রত্যাশা করে তবে বাস্তবে এইচএমএসি-র সাথে স্বাক্ষরিত একটি টোকেন গ্রহণ করে , এটি ভাববে যে পাবলিক কী আসলে একটি HMAC গোপন কী ”"
BennyBechDk

@ লিভিটিকন যে কোনও মতাদর্শে আমি কীভাবে জিএসএন ফাইলটিতে গুগল সরবরাহ করে এমন প্রাইভেট_কিকে ডিকোড করতে পারি? ধন্যবাদ
বাইবেস

46

মূল প্রশ্নটির পরে এই সমস্ত মাস কেটে যাওয়ার পরে, এখন মাইক্রোসফ্ট তাদের নিজস্ব একটি সমাধান তৈরি করেছে তা উল্লেখ করার মতো বিষয়। দেখুন http://blogs.msdn.com/b/vbertocci/archive/2012/11/20/introducing-the-developer-preview-of-the-json-web-token-handler-for-the-microsoft-net -ফ্রেমেওয়ার্ক-4-5 . aspx বিশদ জন্য।


7
এই ব্লগে nuget প্যাকেজ হ্রাস করা হয়। আমি বিশ্বাস করি নতুনটি
স্টান

3
@ স্ট্যান যে লিঙ্কটি দুর্দান্ত, তবে একটি নির্দিষ্ট (এবং এখন নিজেই পুরানো) সংস্করণে সেট করা আছে। এটি সর্বদা সর্বশেষতম সংস্করণে নির্দেশ করবে। nuget.org/packages/System.IdentityModel.Tokens.Jwt
জেফ্রি হারমন

3
কিছু কোড স্নিপেটগুলি ব্যবহার (এনকোডিং / ডিকোডিং, প্রতিসামগ্রী / অ্যাসিম্যাট্রিক) দেখানো খুব দরকারী হবে।
ওহাদ স্নাইডার

20

আমি এটি কখনও ব্যবহার করি নি তবে অনুগেটে জেডাব্লুটি বাস্তবায়ন রয়েছে।

প্যাকেজ: https://nuget.org/packages/JWT

সূত্র: https://github.com/johnsheehan/jwt

.NET 4.0 সামঞ্জস্যপূর্ণ: https://www.nuget.org/packages/jose-jwt/

আপনি এখানেও যেতে পারেন: https://jwt.io/ এবং "লাইব্রেরি" ক্লিক করুন।


12

এখানে একটি কার্যকরী উদাহরণ:

http://zavitax.wordpress.com/2012/12/17/logging-in-with-google-service-account-in-c-jwt/

ওয়েবে ছড়িয়ে ছিটিয়ে থাকা টুকরোগুলি সংগ্রহ করতে বেশ কিছুটা সময় নিয়েছে, ডক্সটি বরং অসম্পূর্ণ ...


অবশেষে একটি সমাধান যা সত্যিই প্লাগ এবং প্লে ছিল। তোমাকে অনেক ধন্যবাদ! এটি আমার পক্ষে কাজ করেছে।
এমকে

6

এটি নেট। নেট এ আমার (গুগল) জেডাব্লুটি বৈধকরণ বাস্তবায়ন। এটি স্ট্যাক ওভারফ্লো এবং গিটহাব গিস্টগুলিতে অন্যান্য বাস্তবায়নের উপর ভিত্তি করে।

using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace QuapiNet.Service
{
    public class JwtTokenValidation
    {
        public async Task<Dictionary<string, X509Certificate2>> FetchGoogleCertificates()
        {
            using (var http = new HttpClient())
            {
                var response = await http.GetAsync("https://www.googleapis.com/oauth2/v1/certs");

                var dictionary = await response.Content.ReadAsAsync<Dictionary<string, string>>();
                return dictionary.ToDictionary(x => x.Key, x => new X509Certificate2(Encoding.UTF8.GetBytes(x.Value)));
            }
        }

        private string CLIENT_ID = "xxx.apps.googleusercontent.com";

        public async Task<ClaimsPrincipal> ValidateToken(string idToken)
        {
            var certificates = await this.FetchGoogleCertificates();

            TokenValidationParameters tvp = new TokenValidationParameters()
            {
                ValidateActor = false, // check the profile ID

                ValidateAudience = true, // check the client ID
                ValidAudience = CLIENT_ID,

                ValidateIssuer = true, // check token came from Google
                ValidIssuers = new List<string> { "accounts.google.com", "https://accounts.google.com" },

                ValidateIssuerSigningKey = true,
                RequireSignedTokens = true,
                IssuerSigningKeys = certificates.Values.Select(x => new X509SecurityKey(x)),
                IssuerSigningKeyResolver = (token, securityToken, kid, validationParameters) =>
                {
                    return certificates
                    .Where(x => x.Key.ToUpper() == kid.ToUpper())
                    .Select(x => new X509SecurityKey(x.Value));
                },
                ValidateLifetime = true,
                RequireExpirationTime = true,
                ClockSkew = TimeSpan.FromHours(13)
            };

            JwtSecurityTokenHandler jsth = new JwtSecurityTokenHandler();
            SecurityToken validatedToken;
            ClaimsPrincipal cp = jsth.ValidateToken(idToken, tvp, out validatedToken);

            return cp;
        }
    }
}

দ্রষ্টব্য, এটি ব্যবহার করার জন্য আপনাকে নুগেট প্যাকেজটিতে একটি রেফারেন্স যুক্ত করতে হবে System.Net.Http.Formatting.Extension। এটি ছাড়া, সংকলক ReadAsAsync<>পদ্ধতিটি চিনতে পারবে না ।


IssuerSigningKeysযদি IssuerSigningKeyResolverসরবরাহ করা থাকে তবে আপনাকে কেন সেট করতে হবে ?
আসিফএম

@ আসিফএমডি সত্যিই জানেন না এবং এই মুহুর্তে এটি পরীক্ষা করতে পারবেন না। সম্ভবত এটি ইস্যুয়ারসাইনিংকি সেট না করেই কাজ করে। শংসাপত্রগুলির অনুরোধ করার জন্য আপনাকে রেজোলভার কোডও পরিবর্তন করতে হবে কারণ অন্যথায় গুগল যখন তার শংসাপত্রগুলি পরিবর্তন করে আপনি কিছু দিনের মধ্যে ত্রুটি পান।
থমাস

এই সহজ পদ্ধতির জন্য +1। সিস্টেমটি সমর্থন করার জন্য প্রধানমন্ত্রী> ইনস্টলড-প্যাকেজ সিস্টেম.আইডেন্টিটি মডেল.টোকেনস.জেডব্লিউ-ভার্সন 5.2.4.অডেন্টিটি মডেল
কার্তিক জয়রামন


1

স্ক্র্যাচ থেকে কোডটি লেখার পরিবর্তে স্ট্যান্ডার্ড এবং বিখ্যাত লাইব্রেরি ব্যবহার করা ভাল।

  1. জেডাব্লুটি টোকেনগুলি এনকোডিং এবং ডিকোডিংয়ের জন্য জেডাব্লুটি
  2. বাউন্সি ক্যাসেল এনক্রিপশন এবং ডিক্রিপশন সমর্থন করে, বিশেষত আরএস 256 এটি এখানে পান

এই লাইব্রেরিগুলি ব্যবহার করে আপনি একটি JWT টোকেন উত্পন্ন করতে পারেন এবং নীচের হিসাবে আরএস 256 ব্যবহার করে সাইন করতে পারেন।

    public string GenerateJWTToken(string rsaPrivateKey)
    {
        var rsaParams = GetRsaParameters(rsaPrivateKey);
        var encoder = GetRS256JWTEncoder(rsaParams);

        // create the payload according to the Google's doc
        var payload = new Dictionary<string, object>
        {
            { "iss", ""},
            { "sub", "" },
            // and other key-values according to the doc
        };

        // add headers. 'alg' and 'typ' key-values are added automatically.
        var header = new Dictionary<string, object>
        {
            { "kid", "{your_private_key_id}" },
        };

        var token = encoder.Encode(header,payload, new byte[0]);

        return token;
    }

    private static IJwtEncoder GetRS256JWTEncoder(RSAParameters rsaParams)
    {
        var csp = new RSACryptoServiceProvider();
        csp.ImportParameters(rsaParams);

        var algorithm = new RS256Algorithm(csp, csp);
        var serializer = new JsonNetSerializer();
        var urlEncoder = new JwtBase64UrlEncoder();
        var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

        return encoder;
    }

    private static RSAParameters GetRsaParameters(string rsaPrivateKey)
    {
        var byteArray = Encoding.ASCII.GetBytes(rsaPrivateKey);
        using (var ms = new MemoryStream(byteArray))
        {
            using (var sr = new StreamReader(ms))
            {
                // use Bouncy Castle to convert the private key to RSA parameters
                var pemReader = new PemReader(sr);
                var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair;
                return DotNetUtilities.ToRSAParameters(keyPair.Private as RsaPrivateCrtKeyParameters);
            }
        }
    }

PS: আরএসএর ব্যক্তিগত কীতে নিম্নলিখিত ফর্ম্যাটটি থাকা উচিত:

----- শুরু করুন আরএসএ প্রাইভেট কী ----- {বেস64 ফর্ম্যাট মান} ----- শেষ আরএসএ প্রাইভেট কী -----


0

জেডাব্লুটিটির মাধ্যমে প্রমাণীকরণ করে জি-স্যুট ব্যবহারকারীগণ এবং গোষ্ঠীগুলিতে অ্যাক্সেস করার জন্য গুগল পরিষেবা অ্যাকাউন্টগুলির জন্য এখানে কেবলমাত্র আরইএসটি-র কাজ করার একটি উদাহরণ । এই Google লাইব্রেরি প্রতিফলন মাধ্যমে শুধুমাত্র সম্ভব ছিল, যেহেতু এই API গুলি গুগল ডকুমেন্টেশন বহির্ভূত ভয়ানক । এমএস প্রযুক্তিগুলিতে কোড ব্যবহার করার জন্য যে কোনও ব্যক্তির গুগল পরিষেবায় সবকিছু কীভাবে একসাথে চলে যায় তা নির্ধারণ করতে খুব কষ্ট হবে।

$iss = "<name>@<serviceaccount>.iam.gserviceaccount.com"; # The email address of the service account.
$sub = "impersonate.user@mydomain.com"; # The user to impersonate (required).
$scope = "https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly";
$certPath = "D:\temp\mycertificate.p12";
$grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer";

# Auxiliary functions
function UrlSafeEncode([String] $Data) {
    return $Data.Replace("=", [String]::Empty).Replace("+", "-").Replace("/", "_");
}

function UrlSafeBase64Encode ([String] $Data) {
    return (UrlSafeEncode -Data ([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Data))));
}

function KeyFromCertificate([System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate) {
    $privateKeyBlob = $Certificate.PrivateKey.ExportCspBlob($true);
    $key = New-Object System.Security.Cryptography.RSACryptoServiceProvider;
    $key.ImportCspBlob($privateKeyBlob);
    return $key;
}

function CreateSignature ([Byte[]] $Data, [System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate) {
    $sha256 = [System.Security.Cryptography.SHA256]::Create();
    $key = (KeyFromCertificate $Certificate);
    $assertionHash = $sha256.ComputeHash($Data);
    $sig = [Convert]::ToBase64String($key.SignHash($assertionHash, "2.16.840.1.101.3.4.2.1"));
    $sha256.Dispose();
    return $sig;
}

function CreateAssertionFromPayload ([String] $Payload, [System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate) {
    $header = @"
{"alg":"RS256","typ":"JWT"}
"@;
    $assertion = New-Object System.Text.StringBuilder;

    $assertion.Append((UrlSafeBase64Encode $header)).Append(".").Append((UrlSafeBase64Encode $Payload)) | Out-Null;
    $signature = (CreateSignature -Data ([System.Text.Encoding]::ASCII.GetBytes($assertion.ToString())) -Certificate $Certificate);
    $assertion.Append(".").Append((UrlSafeEncode $signature)) | Out-Null;
    return $assertion.ToString();
}

$baseDateTime = New-Object DateTime(1970, 1, 1, 0, 0, 0, [DateTimeKind]::Utc);
$timeInSeconds = [Math]::Truncate([DateTime]::UtcNow.Subtract($baseDateTime).TotalSeconds);

$jwtClaimSet = @"
{"scope":"$scope","email_verified":false,"iss":"$iss","sub":"$sub","aud":"https://oauth2.googleapis.com/token","exp":$($timeInSeconds + 3600),"iat":$timeInSeconds}
"@;


$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certPath, "notasecret", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable);
$jwt = CreateAssertionFromPayload -Payload $jwtClaimSet -Certificate $cert;


# Retrieve the authorization token.
$authRes = Invoke-WebRequest -Uri "https://oauth2.googleapis.com/token" -Method Post -ContentType "application/x-www-form-urlencoded" -UseBasicParsing -Body @"
assertion=$jwt&grant_type=$([Uri]::EscapeDataString($grantType))
"@;
$authInfo = ConvertFrom-Json -InputObject $authRes.Content;

$resUsers = Invoke-WebRequest -Uri "https://www.googleapis.com/admin/directory/v1/users?domain=<required_domain_name_dont_trust_google_documentation_on_this>" -Method Get -Headers @{
    "Authorization" = "$($authInfo.token_type) $($authInfo.access_token)"
}

$users = ConvertFrom-Json -InputObject $resUsers.Content;

$users.users | ft primaryEmail, isAdmin, suspended;

0

এখানে ক্লাস এবং ফাংশনগুলির তালিকা রয়েছে:

open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.Logging
open Microsoft.AspNetCore.Authorization
open Microsoft.AspNetCore.Authentication
open Microsoft.AspNetCore.Authentication.JwtBearer
open Microsoft.IdentityModel.Tokens
open System.IdentityModel.Tokens
open System.IdentityModel.Tokens.Jwt
open Microsoft.IdentityModel.JsonWebTokens
open System.Text
open Newtonsoft.Json
open System.Security.Claims
    let theKey = "VerySecretKeyVerySecretKeyVerySecretKey"
    let securityKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes(theKey))
    let credentials = SigningCredentials(securityKey, SecurityAlgorithms.RsaSsaPssSha256)
    let expires = DateTime.UtcNow.AddMinutes(123.0) |> Nullable
    let token = JwtSecurityToken(
                    "lahoda-pro-issuer", 
                    "lahoda-pro-audience",
                    claims = null,
                    expires =  expires,
                    signingCredentials = credentials
        )

    let tokenString = JwtSecurityTokenHandler().WriteToken(token)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.