1. 程式人生 > >IdentityServer4之Implicit(隱式許可)

IdentityServer4之Implicit(隱式許可)

開始 courier uri users lap 自動 eat ddc tap

IdentityServer4之Implicit(隱式許可)

參考

官方文檔:3_interactive_login 、7_javascript_client

概念:隱式許可

認證服務端配置

認證服務ApiResource配置

new ApiResource("api1", "api項目 一")
{
    ApiSecrets = { new Secret("api1pwd".Sha256()) }
},

認證服務Client配置

// OpenID Connect implicit flow client (MVC)
new Client
{
    ClientId = "mvc
", ClientName = "MVC Client", AllowedGrantTypes = GrantTypes.Implicit, AllowAccessTokensViaBrowser = true, AccessTokenType = AccessTokenType.Reference, RedirectUris ={ "http://localhost:5002/signin-oidc", "http://www.implicit.com/signin-oidc" }, PostLogoutRedirectUris
={ "http://localhost:5002/signout-callback-oidc", "http://www.implicit.com/signout-callback-oidc" }, AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, "api1","api2" } },

認證服務Startup配置

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // configure identity server with in-memory stores, keys, clients and scopes
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers());
}

資源服務Api配置

資源服務器Startup配置

services.AddMvcCore()
    .AddAuthorization()
    .AddJsonFormatters();

services.AddAuthentication("Bearer")
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;

        options.ApiName = "api1";  
        options.ApiSecret = "api1pwd";  //對應ApiResources中的密鑰
    });

添加接口

[Route("[controller]")]
[Authorize]
public class IdentityController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var info = from c in User.Claims select new { c.Type, c.Value };
        var list = info.ToList();
        list.Add(new { Type = "api1返回", Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
        return new JsonResult(list);
    }
}

Client客戶端

(A)客戶端通過向授權端點引導資源擁有者的用戶代理開始流程。客戶端包括它的客戶端標識、請求範圍、本地狀態和重定向URI,一旦訪問被許可(或拒絕)授權服務器將傳送用戶代理回到該URI。
(B)授權服務器驗證資源擁有者的身份(通過用戶代理),並確定資源擁有者是否授予或拒絕客戶端的訪問請求。
(C)假設資源擁有者許可訪問,授權服務器使用之前(在請求時或客戶端註冊時)提供的重定向URI重定向用戶代理回到客戶端。重定向URI在URI片段中包含訪問令牌。
(D)用戶代理順著重定向指示向Web托管的客戶端資源發起請求。用戶代理在本地保留片段信息。
(E)Web托管的客戶端資源返回一個網頁(通常是帶有嵌入式腳本的HTML文檔),該網頁能夠訪問包含用戶代理保留的片段的完整重定向URI並提取包含在片段中的訪問令牌(和其他參數)。
(F)用戶代理在本地執行Web托管的客戶端資源提供的提取訪問令牌的腳本。
(G)用戶代理傳送訪問令牌給客戶端。

1、JS Client

// JavaScript Client
new Client
{
    ClientId = "js",
    ClientName = "JavaScript Client",
    AllowedGrantTypes = GrantTypes.Implicit,
    AllowAccessTokensViaBrowser = true, //允許通過瀏覽器傳輸token

    RedirectUris =           { "http://localhost:5009/callback.html" },
    PostLogoutRedirectUris = { "http://localhost:5009/index.html" },
    AllowedCorsOrigins =     { "http://localhost:5009" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    }
},

js client的靜態資源。

技術分享圖片

2、MVC Client

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {
        options.SignInScheme = "Cookies";

        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;

        options.ClientId = "mvc";
        options.ResponseType = "id_token token";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("api1");
    });

需要身份授權的頁面

[Authorize]
public IActionResult Secure()
{
    ViewData["Message"] = "Secure page.";

    return View();
}

調用Api

public async Task<IActionResult> CallApiUsingUserAccessToken()
{
    var accessToken = await HttpContext.GetTokenAsync("access_token");

    var client = new HttpClient();
    client.SetBearerToken(accessToken);
    var content = await client.GetStringAsync("http://localhost:5001/identity");

    ViewBag.Json = JArray.Parse(content).ToString();
    return View("json");
}

獲取token過程解析

Reference形式獲取access_token

1、前後端分離形式認證

隱式許可沒有獲取Authorization Code的過程。

技術分享圖片

4和5是是用戶登錄(資源擁有者授權)。

2和3為Get請求參數如下。

技術分享圖片

使用工具請求實際得到的是一個js Web-Hosted Client Resource返回的靜態腳本資源 。

技術分享圖片

304的回調 # 後的信息不會經過js client 的服務器,直接在瀏覽器解析。

http://localhost:5009/callback.html#
id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjAzMTZkNWQwYTViNTgyYzc0NmJlMmVhZWU1MTg1NzhiIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MTE5NTY1NTMsImV4cCI6MTUxMTk1Njg1MywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoianMiLCJub25jZSI6ImEyOGY5MmRiMjVmNzRkYjQ5YTRhMzU3YTY0YzA2OTU2IiwiaWF0IjoxNTExOTU2NTUzLCJhdF9oYXNoIjoiUldXMU9pTHNzYmVHek1UaHBkbE1xdyIsInNpZCI6ImZiODI5MzQzYWRjN2U4MjUxMjk1OTE1NDBmZDc3ZjBhIiwic3ViIjoiMSIsImF1dGhfdGltZSI6MTUxMTk1NjU1MywiaWRwIjoibG9jYWwiLCJhbXIiOlsicHdkIl19.av1-FqeVdobrPl1QxrIndjpzwTHgoJTclx2xwaOexDapbi-yYe8uOIBQG3hR4B4juM3nBm5GFp0873Yn_ReUD4YAxKlBJuoVxzMVIxSVB2H7RZH5wiMCktY8rgWAV4_lSfDZG1B3n4Ged8gj80b5vlt6rKs48woJiaeDemtLs0EY6lqomENy0MY1lu2TkVco_AyB_ha6jJsLXgCK8U9ttN6862h0HlvDy7KqRpTqfstkcT1JIUkooX3JfUNwru4y38HIxs55_dA9Pq8hfBK--Y7_fRW2_vnDz99Bn0kRcQcfgHXHxcovtNU1MRdFataRtjP6QyC26DyXLcr5d8_QCw&
access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjAzMTZkNWQwYTViNTgyYzc0NmJlMmVhZWU1MTg1NzhiIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MTE5NTY1NTMsImV4cCI6MTUxMTk2MDE1MywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC9yZXNvdXJjZXMiLCJhcGkxIl0sImNsaWVudF9pZCI6ImpzIiwic3ViIjoiMSIsImF1dGhfdGltZSI6MTUxMTk1NjU1MywiaWRwIjoibG9jYWwiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIiwiYXBpMSJdLCJhbXIiOlsicHdkIl19.s1lYjwnuj6PKYwUpKj7CNFhKPEBFqbI51UT8okg1G8d73AU1Tx1KuZpkulxeAbhIqD807TiY_A9-h1shSNTAXOhlcSGR6hZiMHcAU50nFvkNTq16j0wjeGtF5i5xlNJDwvq77cDs0rWnge9dmPtQZNPQXWfNW49_A7BRQUDiAad5S3I0juYsvYS7HThf0dGXRiJwI8ZYNMDRT2jxthZRaImuQFNK3VAFNptb8rJ2R5D3oBbHWDriJ4N-6UUE36ICPenmhy-aykGm_bNjD_unm6sEKy7hGTboGetpgt4F_4fAKJQCCrEzfUohXvQwUSEjQoE1RlZssIFCQTdYnG86sw&
token_type=Bearer&
expires_in=3600&
scope=openid%20profile%20api1&
state=49773b518261412199fb3ece49a043e1&
session_state=yMpEMT7X9xYpM8aBRpJ8IWK60zUi71jXzIgRSaCHO14.6d673e3200de918c6c35a5d61b4ddd2e

技術分享圖片

2、OpenID Connect協議認證

技術分享圖片

7和22是用戶登錄(資源擁有者授權)。

5和23為Get請求參數如下。

技術分享圖片

使用工具請求實際得到的是一個自動提交的表單。

技術分享圖片

登錄完成後的效果。

技術分享圖片

IdentityServer4之Implicit(隱式許可)