溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

asp.net core web api token驗(yàn)證和RestSharp訪問

發(fā)布時(shí)間:2020-09-06 09:29:11 來源:網(wǎng)絡(luò) 閱讀:12299 作者:桂素偉 欄目:編程語言

對與asp.net core web api驗(yàn)證,多種方式,本例子的方式采用的是李爭的《微軟開源跨平臺移動開發(fā)實(shí)踐》中的token驗(yàn)證方式。

Asp.net core web api項(xiàng)目代碼:

首先定義三個(gè)Token相關(guān)的類,一個(gè)Token實(shí)體類,一個(gè)TokenProvider類,一個(gè)TokenProviderOptions類

代碼如下:

/// <summary>
/// Token實(shí)體
/// </summary>
public class TokenEntity
{
    /// <summary>
    /// token字符串
    /// </summary>
    public string access_token { get; set; }
    /// <summary>
    /// 過期時(shí)差
    /// </summary>
    public int expires_in { get; set; }
}
/// <summary>
/// token提供屬性
/// </summary>
public class TokenProviderOptions
{
    /// <summary>
    /// 發(fā)行人
    /// </summary>
    public string Issuer { get; set; }
    /// <summary>
    /// 訂閱者
    /// </summary>
    public string Audience { get; set; }
    /// <summary>
    /// 過期時(shí)間間隔
    /// </summary>
    public TimeSpan Expiration { get; set; } = TimeSpan.FromSeconds(30);
    /// <summary>
    /// 簽名證書
    /// </summary>
    public SigningCredentials SigningCredentials { get; set; }
}
 
/// <summary>
 /// Token提供類
 /// </summary>
 public class TokenProvider
 {
     readonly TokenProviderOptions _options;
     public TokenProvider(TokenProviderOptions options)
     {
         _options = options;
     }
     /// <summary>
     /// 生成令牌
     /// </summary>
     /// <param name="context">http上下文</param>
     /// <param name="username">用戶名</param>
     /// <param name="password">密碼</param>
     /// <param name="role">角色</param>
     /// <returns></returns>
     public async Task<TokenEntity> GenerateToken(HttpContext context, string username, string password, string role)
     {
         var identity = await GetIdentity(username);
         if (identity == null)
         {
             return null;
         }
         var now = DateTime.UtcNow;
         //聲明
         var claims = new Claim[]
         {
             new Claim(JwtRegisteredClaimNames.Sub,username),
             new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
             new Claim(JwtRegisteredClaimNames.Iat,ToUnixEpochDate(now).ToString(),ClaimValueTypes.Integer64),
             new Claim(ClaimTypes.Role,role),
             new Claim(ClaimTypes.Name,username)
         };
         //Jwt安全令牌
         var jwt = new JwtSecurityToken(
             issuer: _options.Issuer,
             audience: _options.Audience,
             claims: claims,
             notBefore: now,
             expires: now.Add(_options.Expiration),
             signingCredentials: _options.SigningCredentials);
         //生成令牌字符串
         var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
         var response = new TokenEntity
         {
             access_token = encodedJwt,
             expires_in = (int)_options.Expiration.TotalSeconds
         };
         return response;
     }
 
     private static long ToUnixEpochDate(DateTime date)
     {
         return (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
     }
     /// <summary>
     /// 查看令牌是否存在
     /// </summary>
     /// <param name="username">用戶名</param>
     /// <returns></returns>
     private Task<ClaimsIdentity> GetIdentity(string username)
     {
         return Task.FromResult(
             new ClaimsIdentity(new System.Security.Principal.GenericIdentity(username, "token"),
             new Claim[] {
                 new Claim(ClaimTypes.Name, username)
             }));
     }
 }

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System.Text;
  
namespace WebApiAuthentication
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }
 
        public IConfigurationRoot Configuration { get; }  
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }
 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
            //自定義密鑰
            var secretKey = "ThisIsASecretKeyForAspNetCoreAPIToken";
            //生成SymmetricSecurityKey密鑰
            var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
            //令牌驗(yàn)證參數(shù)
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidIssuer = "issuer",
                ValidateAudience = true,
                ValidAudience = "audience",
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
 
            };
            //使用Jwt持票人身份驗(yàn)證
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = tokenValidationParameters
            });
 
            app.UseMvc();
        }
    }
}

AccountController.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.Extensions.Options;
 
namespace WebApiAuthentication.Controllers
{   
    [Route("api/v1/[controller]/[action]")]
    public class AccountController : Controller
    {      
        [HttpPost]
        [Authorize(Roles ="admin")]
        public JsonResult ABC()
        {
            return new JsonResult(new
            {
                Name = "張三",
                Age = 12,
                Sex = true,
                User=User.Identity.Name,
               
 
            }, new Newtonsoft.Json.JsonSerializerSettings());
        }
        [AllowAnonymous]
        public IActionResult Login()
        {
            return View();
        }
        /// <summary>
        /// 登錄action
        /// </summary>
        /// <param name="username">用戶名</param>
        /// <param name="password">密碼</param>
        /// <param name="role">角色</param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> Login(string username, string password,string role)
        {
            var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ThisIsASecretKeyForAspNetCoreAPIToken"));
            var options = new TokenProviderOptions
            {
                Audience = "audience",
                Issuer = "issuer",
                SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
            };
            var tpm = new TokenProvider(options);
            var token = await tpm.GenerateToken(HttpContext, username, password,role);
            if (null != token)
            {
                return new JsonResult(token);
            }
            else
            {
                return NotFound();
            }
        }
    }
}

客戶端代代碼是用RestSharp來實(shí)現(xiàn),代碼如下:

using RestSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WebApiAuthenticationClientTest
{
    class Program
    {
        static void Main(string[] args)
        {         
            dynamic token = null;
            while (true)
            {
                Console.WriteLine("1、登錄 2、查詢數(shù)據(jù) ");
                var mark = Console.ReadLine();
                var  stopwatch = new Stopwatch();
                stopwatch.Start();
                switch (mark)
                {
                    case "1":
                        var loginClient = new RestClient("http://localhost:5000");
                        var loginRequest = new RestRequest("/api/v1/account/login", Method.POST);
                        loginRequest.AddParameter("username", "dsfsdf");
                        loginRequest.AddParameter("password", "111111");
                        //或用用戶名密碼查詢對應(yīng)角色
                        loginRequest.AddParameter("role", "admin");
                        IRestResponse loginResponse = loginClient.Execute(loginRequest);
                        var loginContent = loginResponse.Content;
                        Console.WriteLine(loginContent);
                        token = Newtonsoft.Json.JsonConvert.DeserializeObject(loginContent);
                        break;
                    case "2":
                        var client = new RestClient("http://localhost:5000");
                        //這里要在獲取的令牌字符串前加Bearer
                        string tk = "Bearer " + Convert.ToString(token?.access_token);
                        client.AddDefaultHeader("Authorization", tk);
                        var request = new RestRequest("/api/v1/account/abc", Method.POST);
                        IRestResponse response = client.Execute(request);
                        var content = response.Content;              
                        Console.WriteLine($"狀態(tài):{response.StatusCode}  返回結(jié)果:{content}");
                        break;            
                }    
                stopwatch.Stop();
                TimeSpan timespan = stopwatch.Elapsed;
                Console.WriteLine($"間隔時(shí)間:{timespan.TotalSeconds}");
            }
        }
    }
}


運(yùn)行服務(wù)端,再運(yùn)行客戶端,測試如下,沒有登錄前的查詢返回狀態(tài)是Unauthorized,登錄后再查詢的狀態(tài)是OK

asp.net core web api token驗(yàn)證和RestSharp訪問

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI