Xác thực JWT cho API Web ASP.NET


264

Tôi đang cố gắng hỗ trợ mã thông báo mang JWT (Mã thông báo web JSON) trong ứng dụng API web của tôi và tôi đang bị lạc.

Tôi thấy hỗ trợ cho .NET Core và cho các ứng dụng OWIN.
Tôi hiện đang lưu trữ ứng dụng của mình trong IIS.

Làm thế nào tôi có thể đạt được mô-đun xác thực này trong ứng dụng của mình? Có cách nào tôi có thể sử dụng <authentication>cấu hình tương tự như cách tôi sử dụng biểu mẫu / xác thực Windows không?

Câu trả lời:


611

Tôi đã trả lời câu hỏi này: Cách bảo mật API Web ASP.NET 4 năm trước bằng cách sử dụng HMAC.

Giờ đây, rất nhiều thứ đã thay đổi trong bảo mật, đặc biệt là JWT đang trở nên phổ biến. Ở đây, tôi sẽ cố gắng giải thích cách sử dụng JWT theo cách đơn giản và cơ bản nhất có thể, vì vậy chúng tôi sẽ không bị lạc khỏi rừng của OWIN, Oauth2, ASP.NET Identity ... :).

Nếu bạn không biết mã thông báo JWT, bạn cần xem qua một chút về:

https://tools.ietf.org/html/rfc7519

Về cơ bản, mã thông báo JWT trông giống như:

<base64-encoded header>.<base64-encoded claims>.<base64-encoded signature>

Thí dụ:

chiều cao của chúng tôi để tin về việc để chiều cao về việc để cho đến việc: điều gì đó về việc để chiều cao như vậy

Mã thông báo JWT có ba phần:

  1. Tiêu đề: Định dạng JSON được mã hóa trong Base64
  2. Khiếu nại: Định dạng JSON được mã hóa trong Base64.
  3. Chữ ký: Được tạo và ký dựa trên Tiêu đề và Khiếu nại được mã hóa trong Base64.

Nếu bạn sử dụng trang web jwt.io với mã thông báo ở trên, bạn có thể giải mã mã thông báo và xem nó như dưới đây:

nhập mô tả hình ảnh ở đây

Về mặt kỹ thuật, JWT sử dụng chữ ký được ký từ các tiêu đề và khiếu nại với thuật toán bảo mật được chỉ định trong các tiêu đề (ví dụ: HMACSHA256). Do đó, JWT bắt buộc phải được chuyển qua HTTP nếu bạn lưu trữ bất kỳ thông tin nhạy cảm nào trong các khiếu nại.

Bây giờ, để sử dụng xác thực JWT, bạn không thực sự cần một phần mềm trung gian OWIN nếu bạn có một hệ thống Api Web kế thừa. Khái niệm đơn giản là cách cung cấp mã thông báo JWT và cách xác thực mã thông báo khi có yêu cầu. Đó là nó.

Quay lại bản demo, để giữ cho mã thông báo JWT nhẹ, tôi chỉ lưu trữ usernameexpiration time trong JWT. Nhưng theo cách này, bạn phải xây dựng lại danh tính địa phương mới (hiệu trưởng) để thêm nhiều thông tin như: vai trò .. nếu bạn muốn thực hiện ủy quyền vai trò. Nhưng, nếu bạn muốn thêm thông tin vào JWT, điều đó tùy thuộc vào bạn: nó rất linh hoạt.

Thay vì sử dụng phần mềm trung gian OWIN, bạn chỉ cần cung cấp điểm cuối mã thông báo JWT bằng cách sử dụng hành động từ bộ điều khiển:

public class TokenController : ApiController
{
    // This is naive endpoint for demo, it should use Basic authentication
    // to provide token or POST request
    [AllowAnonymous]
    public string Get(string username, string password)
    {
        if (CheckUser(username, password))
        {
            return JwtManager.GenerateToken(username);
        }

        throw new HttpResponseException(HttpStatusCode.Unauthorized);
    }

    public bool CheckUser(string username, string password)
    {
        // should check in the database
        return true;
    }
}

Đây là một hành động ngây thơ; trong sản xuất, bạn nên sử dụng yêu cầu POST hoặc điểm cuối Xác thực cơ bản để cung cấp mã thông báo JWT.

Làm thế nào để tạo mã thông báo dựa trên username?

Bạn có thể sử dụng gói NuGet được gọi System.IdentityModel.Tokens.Jwttừ Microsoft để tạo mã thông báo hoặc thậm chí một gói khác nếu bạn muốn. Trong bản demo, tôi sử dụng HMACSHA256với SymmetricKey:

/// <summary>
/// Use the below code to generate symmetric Secret Key
///     var hmac = new HMACSHA256();
///     var key = Convert.ToBase64String(hmac.Key);
/// </summary>
private const string Secret = "db3OIsj+BXE9NZDy0t8W3TcNekrF+2d/1sFnWG4HnV8TZY30iTOdtVWJG8abWvB1GlOgJuQZdcF2Luqm/hccMw==";

public static string GenerateToken(string username, int expireMinutes = 20)
{
    var symmetricKey = Convert.FromBase64String(Secret);
    var tokenHandler = new JwtSecurityTokenHandler();

    var now = DateTime.UtcNow;
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, username)
        }),

        Expires = now.AddMinutes(Convert.ToInt32(expireMinutes)),

        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(symmetricKey), 
            SecurityAlgorithms.HmacSha256Signature)
    };

    var stoken = tokenHandler.CreateToken(tokenDescriptor);
    var token = tokenHandler.WriteToken(stoken);

    return token;
}

Điểm cuối để cung cấp mã thông báo JWT đã hoàn tất. Bây giờ, làm thế nào để xác nhận JWT khi yêu cầu đến? Trong bản demo tôi đã xây dựng JwtAuthenticationAttributekế thừa từ đó IAuthenticationFilter(chi tiết hơn về bộ lọc xác thực ở đây ).

Với thuộc tính này, bạn có thể xác thực bất kỳ hành động nào: bạn chỉ cần đặt thuộc tính này vào hành động đó.

public class ValueController : ApiController
{
    [JwtAuthentication]
    public string Get()
    {
        return "value";
    }
}

Bạn cũng có thể sử dụng phần mềm trung gian OWIN hoặc DelegateHander nếu bạn muốn xác thực tất cả các yêu cầu đến cho WebAPI của mình (không dành riêng cho Trình điều khiển hoặc hành động)

Dưới đây là phương pháp cốt lõi từ bộ lọc xác thực:

private static bool ValidateToken(string token, out string username)
{
    username = null;

    var simplePrinciple = JwtManager.GetPrincipal(token);
    var identity = simplePrinciple.Identity as ClaimsIdentity;

    if (identity == null)
        return false;

    if (!identity.IsAuthenticated)
        return false;

    var usernameClaim = identity.FindFirst(ClaimTypes.Name);
    username = usernameClaim?.Value;

    if (string.IsNullOrEmpty(username))
       return false;

    // More validate to check whether username exists in system

    return true;
}

protected Task<IPrincipal> AuthenticateJwtToken(string token)
{
    string username;

    if (ValidateToken(token, out username))
    {
        // based on username to get more information from database 
        // in order to build local identity
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username)
            // Add more claims if needed: Roles, ...
        };

        var identity = new ClaimsIdentity(claims, "Jwt");
        IPrincipal user = new ClaimsPrincipal(identity);

        return Task.FromResult(user);
    }

    return Task.FromResult<IPrincipal>(null);
}

Quy trình công việc là, sử dụng thư viện JWT (gói NuGet ở trên) để xác thực mã thông báo JWT và sau đó quay lại ClaimsPrincipal. Bạn có thể thực hiện xác nhận nhiều hơn như kiểm tra xem người dùng có tồn tại trên hệ thống của bạn không và thêm các xác nhận tùy chỉnh khác nếu bạn muốn. Mã để xác thực mã thông báo JWT và lấy lại tiền gốc:

public static ClaimsPrincipal GetPrincipal(string token)
{
    try
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

        if (jwtToken == null)
            return null;

        var symmetricKey = Convert.FromBase64String(Secret);

        var validationParameters = new TokenValidationParameters()
        {
            RequireExpirationTime = true,
            ValidateIssuer = false,
            ValidateAudience = false,
            IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
        };

        SecurityToken securityToken;
        var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);

        return principal;
    }
    catch (Exception)
    {
        //should write log
        return null;
    }
}

Nếu mã thông báo JWT được xác thực và tiền gốc được trả lại, bạn nên xây dựng một danh tính cục bộ mới và đưa thêm thông tin vào đó để kiểm tra ủy quyền vai trò.

Hãy nhớ thêm config.Filters.Add(new AuthorizeAttribute());(ủy quyền mặc định) trong phạm vi toàn cầu để ngăn chặn mọi yêu cầu ẩn danh đối với tài nguyên của bạn.

Bạn có thể sử dụng Postman để kiểm tra bản demo:

Mã thông báo yêu cầu (ngây thơ như tôi đã đề cập ở trên, chỉ để dùng thử):

GET http://localhost:{port}/api/token?username=cuong&password=1

Đặt mã thông báo JWT trong tiêu đề cho yêu cầu được ủy quyền, ví dụ:

GET http://localhost:{port}/api/value

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImN1b25nIiwibmJmIjoxNDc3NTY1MjU4LCJleHAiOjE0Nzc1NjY0NTgsImlhdCI6MTQ3NzU2NTI1OH0.dSwwufd4-gztkLpttZsZ1255oEzpWCJkayR_4yvNL1s

Bản demo được đặt ở đây: https://github.com/cuongle/WebApi.Jwt


5
Được giải thích tốt bởi @Cuong Le nhưng tôi muốn thêm nhiều hơn: Nếu bạn đang sử dụng OWIN, hãy kiểm tra UseJwtBearerAuthentication có sẵn trong Microsoft.Owin.Security.Jwt bạn có thể sử dụng phần mềm trung gian owin này trên WebAPI để xác thực mọi yêu cầu đến tự động. sử dụng lớp khởi động owin để đăng ký phần mềm trung gian
Jek

5
@AmirPopovich Bạn không cần đặt mã thông báo cho phản hồi, mã thông báo cần được lưu trữ ở một nơi khác ở phía máy khách, đối với web, bạn có thể đặt vào bộ nhớ cục bộ, bất cứ khi nào bạn gửi yêu cầu HTTP, đặt mã thông báo vào tiêu đề.
cuongle

7
Wow đây là khám phá đơn giản nhất mà tôi đã thấy trong một thời gian dài. +100 nếu tôi có thể
gyozo kudor

4
@Homam: Xin lỗi vì câu trả lời muộn này, cách tốt nhất để tạo là: varhmac = new HMACSHA256();var key = Convert.ToBase64String(hmac.Key);
cuongle

4
Bất cứ ai sử dụng mã trình diễn từ repo của CườngLe đều nhận thấy có một lỗi trong đó các yêu cầu không có tiêu đề ủy quyền không được xử lý, có nghĩa là bất kỳ truy vấn nào mà không ai có thể vượt qua (không bảo mật điểm cuối!). Có một yêu cầu kéo từ @magicleon để khắc phục vấn đề này tại đây: github.com/cuongle/WebApi.Jwt/pull/4
Chucky

11

Tôi đã quản lý để đạt được nó với nỗ lực tối thiểu (đơn giản như với ASP.NET Core).

Cho rằng tôi sử dụng Startup.cstập tin và Microsoft.Owin.Security.Jwtthư viện OWIN .

Để ứng dụng được nhấn, Startup.cschúng tôi cần sửa đổi Web.config:

<configuration>
  <appSettings>
    <add key="owin:AutomaticAppStartup" value="true" />
    ...

Đây là cách Startup.csnhìn:

using MyApp.Helpers;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Jwt;
using Owin;

[assembly: OwinStartup(typeof(MyApp.App_Start.Startup))]

namespace MyApp.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidAudience = ConfigHelper.GetAudience(),
                        ValidIssuer = ConfigHelper.GetIssuer(),
                        IssuerSigningKey = ConfigHelper.GetSymmetricSecurityKey(),
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true
                    }
                });
        }
    }
}

Ngày nay, nhiều bạn sử dụng ASP.NET Core, vì vậy bạn có thể thấy nó không khác nhiều so với những gì chúng ta có ở đó.

Nó thực sự làm tôi bối rối trước tiên, tôi đã cố gắng thực hiện các nhà cung cấp tùy chỉnh, v.v. Nhưng tôi không ngờ nó lại đơn giản đến thế. OWINChỉ là đá!

Chỉ có một điều cần đề cập - sau khi tôi kích hoạt NSWagthư viện Khởi động OWIN ngừng hoạt động đối với tôi (ví dụ: một số bạn có thể muốn tự động tạo proxy HTTP bản mô tả cho ứng dụng Angular).

Giải pháp cũng rất đơn giản - tôi đã thay thế NSWag với Swashbucklevà không có bất kỳ vấn đề hơn nữa.


Ok, bây giờ chia sẻ ConfigHelper mã:

public class ConfigHelper
{
    public static string GetIssuer()
    {
        string result = System.Configuration.ConfigurationManager.AppSettings["Issuer"];
        return result;
    }

    public static string GetAudience()
    {
        string result = System.Configuration.ConfigurationManager.AppSettings["Audience"];
        return result;
    }

    public static SigningCredentials GetSigningCredentials()
    {
        var result = new SigningCredentials(GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256);
        return result;
    }

    public static string GetSecurityKey()
    {
        string result = System.Configuration.ConfigurationManager.AppSettings["SecurityKey"];
        return result;
    }

    public static byte[] GetSymmetricSecurityKeyAsBytes()
    {
        var issuerSigningKey = GetSecurityKey();
        byte[] data = Encoding.UTF8.GetBytes(issuerSigningKey);
        return data;
    }

    public static SymmetricSecurityKey GetSymmetricSecurityKey()
    {
        byte[] data = GetSymmetricSecurityKeyAsBytes();
        var result = new SymmetricSecurityKey(data);
        return result;
    }

    public static string GetCorsOrigins()
    {
        string result = System.Configuration.ConfigurationManager.AppSettings["CorsOrigins"];
        return result;
    }
}

Một khía cạnh quan trọng khác - Tôi đã gửi mã thông báo JWT qua tiêu đề Ủy quyền , vì vậy mã bản in tìm cho tôi như sau:

(mã dưới đây được tạo bởi NSWag )

@Injectable()
export class TeamsServiceProxy {
    private http: HttpClient;
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) {
        this.http = http;
        this.baseUrl = baseUrl ? baseUrl : "https://localhost:44384";
    }

    add(input: TeamDto | null): Observable<boolean> {
        let url_ = this.baseUrl + "/api/Teams/Add";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = JSON.stringify(input);

        let options_ : any = {
            body: content_,
            observe: "response",
            responseType: "blob",
            headers: new HttpHeaders({
                "Content-Type": "application/json", 
                "Accept": "application/json",
                "Authorization": "Bearer " + localStorage.getItem('token')
            })
        };

Xem phần tiêu đề - "Authorization": "Bearer " + localStorage.getItem('token')


I replaced NSWag with Swashbuckle and didn't have any further issues.Swashbuckle có khả năng tạo các tệp bản thảo hay đó là thứ bạn tự thêm vào?
đè bẹp

@crush swashbucle là một thư viện phụ trợ cung cấp json, giống như thư viện nuget nswag chỉ tốt hơn. Để tạo tệp bản thảo, bạn vẫn nên sử dụng gói nswag từ npm.
Alex Herman

Đúng vậy, đôi khi tôi đã có swashbuckle trong dự án của mình, có vẻ như bạn đang đề xuất rằng nó có thể tạo các mô hình TypeScript thay vì nswag. Tôi không phải là một fan hâm mộ của nswag ... nó nặng. Tôi đã tạo chuyển đổi C # -> TypeScript của riêng mình được nối vào Swashbuckle - tạo các tệp dưới dạng quá trình xây dựng sau và xuất bản chúng thành nguồn cấp dữ liệu npm cho các dự án của chúng tôi. Tôi chỉ muốn chắc chắn rằng tôi đã không bỏ qua một dự án Swashbuckle đã làm điều tương tự.
nghiền nát

8

Đây là một triển khai rất tối thiểu và an toàn của Xác thực dựa trên Khiếu nại bằng cách sử dụng mã thông báo JWT trong API Web ASP.NET.

trước hết, bạn cần trưng ra một điểm cuối trả về mã thông báo JWT với các khiếu nại được gán cho người dùng:

 /// <summary>
        /// Login provides API to verify user and returns authentication token.
        /// API Path:  api/account/login
        /// </summary>
        /// <param name="paramUser">Username and Password</param>
        /// <returns>{Token: [Token] }</returns>
        [HttpPost("login")]
        [AllowAnonymous]
        public async Task<IActionResult> Login([FromBody] UserRequestVM paramUser, CancellationToken ct)
        {

            var result = await UserApplication.PasswordSignInAsync(paramUser.Email, paramUser.Password, false, lockoutOnFailure: false);

            if (result.Succeeded)
            {
                UserRequestVM request = new UserRequestVM();
                request.Email = paramUser.Email;


                ApplicationUser UserDetails = await this.GetUserByEmail(request);
                List<ApplicationClaim> UserClaims = await this.ClaimApplication.GetListByUser(UserDetails);

                var Claims = new ClaimsIdentity(new Claim[]
                                {
                                    new Claim(JwtRegisteredClaimNames.Sub, paramUser.Email.ToString()),
                                    new Claim(UserId, UserDetails.UserId.ToString())
                                });


                //Adding UserClaims to JWT claims
                foreach (var item in UserClaims)
                {
                    Claims.AddClaim(new Claim(item.ClaimCode, string.Empty));
                }

                var tokenHandler = new JwtSecurityTokenHandler();
                  // this information will be retrived from you Configuration
                //I have injected Configuration provider service into my controller
                var encryptionkey = Configuration["Jwt:Encryptionkey"];
                var key = Encoding.ASCII.GetBytes(encryptionkey);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Issuer = Configuration["Jwt:Issuer"],
                    Subject = Claims,

                // this information will be retrived from you Configuration
                //I have injected Configuration provider service into my controller
                    Expires = DateTime.UtcNow.AddMinutes(Convert.ToDouble(Configuration["Jwt:ExpiryTimeInMinutes"])),

                    //algorithm to sign the token
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)

                };

                var token = tokenHandler.CreateToken(tokenDescriptor);
                var tokenString = tokenHandler.WriteToken(token);

                return Ok(new
                {
                    token = tokenString
                });
            }

            return BadRequest("Wrong Username or password");
        }

bây giờ bạn cần Thêm Xác thực vào các dịch vụ của mình ConfigureServicestrong startup.cs của bạn để thêm xác thực JWT làm dịch vụ xác thực mặc định như thế này:

services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
             .AddJwtBearer(cfg =>
             {
                 cfg.RequireHttpsMetadata = false;
                 cfg.SaveToken = true;
                 cfg.TokenValidationParameters = new TokenValidationParameters()
                 {
                     //ValidateIssuerSigningKey = true,
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWT:Encryptionkey"])),
                     ValidateAudience = false,
                     ValidateLifetime = true,
                     ValidIssuer = configuration["Jwt:Issuer"],
                     //ValidAudience = Configuration["Jwt:Audience"],
                     //IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Key"])),
                 };
             });

bây giờ bạn có thể thêm các chính sách cho các dịch vụ ủy quyền của mình như thế này:

services.AddAuthorization(options =>
            {
                options.AddPolicy("YourPolicyNameHere",
                                policy => policy.RequireClaim("YourClaimNameHere"));
            });

THAY ĐỔI , Bạn cũng có thể (không cần thiết) đưa ra tất cả các khiếu nại của mình từ cơ sở dữ liệu của mình vì điều này sẽ chỉ chạy một lần khi khởi động ứng dụng của bạn và thêm chúng vào các chính sách như sau:

  services.AddAuthorization(async options =>
            {
                var ClaimList = await claimApplication.GetList(applicationClaim);
                foreach (var item in ClaimList)
                {                        
                    options.AddPolicy(item.ClaimCode, policy => policy.RequireClaim(item.ClaimCode));                       
                }
            });

bây giờ bạn có thể đặt bộ lọc Chính sách cho bất kỳ phương thức nào bạn muốn được ủy quyền như thế này:

 [HttpPost("update")]
        [Authorize(Policy = "ACC_UP")]
        public async Task<IActionResult> Update([FromBody] UserRequestVM requestVm, CancellationToken ct)
        {
//your logic goes here
}

Hi vọng điêu nay co ich


3

Tôi nghĩ bạn nên sử dụng một số máy chủ của bên 3d để hỗ trợ mã thông báo JWT và không có hỗ trợ JWT nào trong WEB API 2.

Tuy nhiên, có một dự án OWIN để hỗ trợ một số định dạng mã thông báo đã ký (không phải JWT). Nó hoạt động như một giao thức OAuth giảm để chỉ cung cấp một hình thức xác thực đơn giản cho một trang web.

Bạn có thể đọc thêm về nó, ví dụ ở đây .

Nó khá dài, nhưng hầu hết các phần là chi tiết với bộ điều khiển và Nhận dạng ASP.NET mà bạn có thể không cần. Quan trọng nhất là

Bước 9: Thêm hỗ trợ cho Thế hệ Token OAuth Bearer

Bước 12: Kiểm tra API Back-end

Ở đó bạn có thể đọc cách thiết lập điểm cuối (ví dụ: "/ mã thông báo") mà bạn có thể truy cập từ lối vào (và chi tiết về định dạng của yêu cầu).

Các bước khác cung cấp chi tiết về cách kết nối điểm cuối đó với cơ sở dữ liệu, v.v. và bạn có thể chọn các phần mà bạn yêu cầu.


2

Trong trường hợp của tôi, JWT được tạo bởi một API riêng vì vậy ASP.NET chỉ cần giải mã và xác thực nó. Ngược lại với câu trả lời được chấp nhận, chúng tôi đang sử dụng RSA, một thuật toán không đối xứng, do đó, SymmetricSecurityKeylớp được đề cập ở trên sẽ không hoạt động.

Đây là kết quả.

using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Threading;
using System.Threading.Tasks;

    public static async Task<JwtSecurityToken> VerifyAndDecodeJwt(string accessToken)
    {
        try
        {
            var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{securityApiOrigin}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
            var openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None);
            var validationParameters = new TokenValidationParameters()
            {
                ValidateLifetime = true,
                ValidateAudience = false,
                ValidateIssuer = false,
                RequireSignedTokens = true,
                IssuerSigningKeys = openIdConfig.SigningKeys,
            };
            new JwtSecurityTokenHandler().ValidateToken(accessToken, validationParameters, out var validToken);
            // threw on invalid, so...
            return validToken as JwtSecurityToken;
        }
        catch (Exception ex)
        {
            logger.Info(ex.Message);
            return null;
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.