IdentityServer4入門二

在 IdentityServer4入門一 咱們準備好了一個認證的服務端,這裏作一個須要保護的API服務html

首先,向解決方案新增一個項目。咱們一樣使用入門一的方式新增一個asp.net core Web程序(模型視圖控制器)ios

一樣的將端口修改一下,API的端口咱們使用44301。打開Properties\launchSettings.json文件web

 

利用nuget安裝引用json

Microsoft.AspNetCore.Authentication.JwtBearerapi

 新增控制器瀏覽器

在controlers目錄下新增「API控制器-空」,名爲:IdentityController安全

[Route("api/[controller]")]
[ApiController]
[Authorize] public class IdentityController : ControllerBase { [HttpGet] public IActionResult Get() { return new JsonResult(from c in User.Claims select new { c.Type, c.Value }); } }

  

修改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.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace API
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
//增長這一段
            services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = "https://localhost:44300";
                //options.RequireHttpsMetadata = false;
                options.Audience = "api1";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseAuthentication();//增長這一句
           
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

  

以上代碼聲明要使用JWTBearer認證做爲安全方式。Bearer認證(也叫作令牌認證)是一種HTTP認證方案,其中包含的安全令牌的叫作Bearer Token。所以Bearer認證的核心是Token。那如何確保Token的安全是重中之重。一種方式是使用Https,另外一種方式就是對Token進行加密簽名。而JWT就是一種比較流行的Token編碼方式。網絡

 JWT(Json Web Token)

Json web token (JWT), 是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準(RFC 7519)。該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登陸(SSO)場景。JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。app

JWT有三部分組成:

<header>.<payload>.<signature>

  1. Header:由algtyp組成,alg是algorithm的縮寫,typ是type的縮寫,指定token的類型。該部分使用Base64Url編碼。
  2. Payload:主要用來存儲信息,包含各類聲明,一樣該部分也由BaseURL編碼。
  3. Signature:簽名,使用服務器端的密鑰進行簽名。以確保Token未被篡改。

好了,如今試試調試運行,並在地址欄錄入 https://localhost:44301/api/identity ,固然你在IE看的話,什麼都看不到,空白的一頁,其實瀏覽器收到服務器的錯誤碼401。

 

爲了進一步驗證,下面寫一個console的程序調用一下這個API

新增項目:控制檯應用(.NET core),名爲:ClientConsole

利用nuget安裝如下引用

IdentityServer4

修改主方法以下

static async Task Main(string[] args)
{
    //Console.WriteLine("Hello World!");            
    var client = new HttpClient();

    string token = "empty token";
    client.SetBearerToken(token);

    var response = await client.GetAsync("https://localhost:44301/api/identity");
    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(JArray.Parse(content));
    }
}

  

以上程序結果是response.IsSuccessStatusCode==false,因此直接打印respone.StatusCode

 

 

 如下代碼是完整的過程:向44300受權訪問"api1",獲得token後,訪問44301的api/identity

using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace ClientConsole
{
    class Program
    {
        static async Task Main(string[] args)
        {
            //Console.WriteLine("Hello World!");            
            var client = new HttpClient();
            // discover endpoints from metadata
            var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44300");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }
            // request token
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "client",
                ClientSecret = "secret",
                Scope = "api1"
            });

            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }
            // call api
            string tokenStr = tokenResponse.AccessToken;
            //string tokenStr = "test";
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenStr);

            var response = await apiClient.GetAsync("https://localhost:44301/api/identity");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
        }
    }
}

  

正常的話,應能看到相似內容

相關文章
相關標籤/搜索