IdentityServer4在Asp.Net Core中的應用(三)

    今天的內容是受權模式中的簡化模式,仍是先看如下受權流程圖:git

在這種模式中咱們將與OpenID結合使用,因此首先咱們要了解OpenID和OAuth的區別,關於他們的區別,在我上一篇博客《理解OpenID和OAuth的區別》中作了的一些簡要的介紹,這裏再也不多說。github

        受權服務器咱們仍是在以前的基礎上改動,首先咱們須要在Config類裏面添加對OpenID Connect Identity Scopes的支持,與OAuth2.0相比,OIDC(OpenID Connect)一樣須要Scopes的概念,他也須要保護Scopes範圍的內容而也須要讓用戶去訪問的內容,可是OIDC中這裏的範圍並非用戶要訪問的API,而是用戶標識、用戶名、Email等信息。bash

        添加對OpenId(SubjectId) Profile(first name last name etc...)的支持範圍,並返回一個IdentityReSource的集合,添加如下代碼:服務器

//添加對OpenID Profile範圍的支持
 public static IEnumerable<IdentityResource> GetIdentityResources()
 {
       return new List<IdentityResource>{
              new IdentityResources.OpenId(),
              new IdentityResources.Profile(),
         };
 }

再天際一個客戶端,基於Implicit受權模式,添加如下代碼:app

new Client(){
    ClientId="impClient",
    AllowedGrantTypes=GrantTypes.Implicit,

    //用於登陸成功後的RedirectUri
    RedirectUris={"http://localhost:5004/signin-oidc"},

    //用於註銷後的RedirectUri
    PostLogoutRedirectUris={"http://localhost:5004/signout-callback-oidc"},

    //容許訪問的範圍
    AllowedScopes={
             IdentityServerConstants.StandardScopes.OpenId,
             IdentityServerConstants.StandardScopes.Profile
           }
  }

下面咱們還要將IdentityResource注入到IdentityServer中,在ConfigureService中,添加:curl

.AddInMemoryIdentityResources(Config.GetIdentityResources())async

修改返回的TestUser的方法,在每個用戶中添加一個聲明屬性的集合,返回一個name和address信息,改動以下:學習

return new List<TestUser>{
     new TestUser(){
         SubjectId="1",
         Username="allen",
         Password="123456",
         Claims=new List<Claim>
              {
                  new Claim("name","Allen"),
                  new Claim("address","http://allen.com")
              }
         },
      new TestUser(){
         SubjectId="2",
         Username="alisa",
         Password="123456",
         Claims=new List<Claim>
                {
                    new Claim("name","Alisa"),
                    new Claim("address","http://alisa.com")
                }
         }

OIDC所需的全部協議已經內置在IdentityServer4中了,須要爲登陸、註銷、贊成受權內容以及錯誤等提供UI的部分,IdentityServer4提供了一個簡單的基於MVC的UI界面,咱們能夠直接download到咱們的服務端裏,在控制檯使用命令:ui

若是你是Windows系統,使用如下命令:this

iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))

若是你是MacOS或者Linux用戶,使用:

\curl -L https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.sh | bash

執行完成後,會發現多了一個QuickStart文件夾,放置了所用到的Controller,Views文件夾下也放置了對應的視圖,

因爲我建立的是WebApi項目,因此還要在StartUp.cs裏面將原來咱們註釋掉的app.UseMvc()解開,另外在配置默認路由前還要添加使用靜態文件,以使用咱們的靜態文件夾下的樣式,app.UseStaticFiles(); 以上內容都修改完成後,下面咱們新建一個Mvc的項目,去請求咱們的受權服務器,如何建立再也不贅述,建立完成後添加對OIDC認證的支持,在ConfigureServices的方法中添加如下代碼:

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 System.IdentityModel.Tokens.Jwt;

namespace MvcClient
{
    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)
        {
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            //添加認證服務到DI中,
            services.AddAuthentication(options=>{
                //使用Cookies做爲惟一的認證用戶的主要手段
                options.DefaultScheme="Cookies";
                //須要用戶登陸纔可進入該應用程序,使用OpenID Connect scheme
                options.DefaultChallengeScheme="oidc";
            })
            //添加能夠處理Cookie的處理程序
            .AddCookie("Cookies")

            //配置OpenID Connect協議
            .AddOpenIdConnect("oidc",options=>{
                //OIDC協議執行完成,發佈Cookie
                options.SignInScheme="Cookies";

                //受權服務器地址
                options.Authority="http://localhost:5000";
                options.RequireHttpsMetadata=false;
                //指定客戶端Id
                options.ClientId="impClient";
                //保存令牌在Cookie中
                options.SaveTokens=true;
            });

            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (!env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            //添加認證中間件
            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

注意配置啓動時將MvcClient啓動端口改成5004,由於我在服務端指定的客戶端的端口爲5004,接着咱們添加一個Action,使他須要進行受權訪問,

[Authorize]
public IActionResult Authorize()
{
      return View();
}

並添加對應的視圖,展現用戶信息:

@{
    ViewData["Title"] = "Authorize";
}

<h2>Claims:</h2>
<dl>
@foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }
</dl>

至此,咱們的配置就完成了,下面咱們運行看下效果,首先run下服務端,再啓動咱們的客戶端,客戶端點擊Authorize菜單:

這個就對應咱們那個須要QQ登陸的界面了,須要經過認證,咱們輸入咱們事先配置的用戶名和密碼,allen 123456,

到consent頁面是要經過咱們的受權,將咱們用戶信息共享給客戶端,如今咱們選擇用戶profile,點擊容許:

當咱們點擊不容許讀取用戶信息的時候:

在不容許讀取的狀況下,咱們是沒法看到用戶名的。下面咱們再添加一個註銷登陸的方法,

//註銷登陸
public async Task LogOut()
{
     await HttpContext.SignOutAsync("Cookies");
     await HttpContext.SignOutAsync("oidc");
}

執行退出:

至此整個Implicit受權模式的過程就進行完了。

 

掃描二維碼關注個人公衆號,共同窗習,共同進步!

相關文章
相關標籤/搜索