日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IdentityServer4 实现 OpenID Connect 和 OAuth 2.0

發布時間:2025/1/21 编程问答 91 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IdentityServer4 实现 OpenID Connect 和 OAuth 2.0 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于 OAuth 2.0 的相關內容,點擊查看:ASP.NET WebApi OWIN 實現 OAuth 2.0

OpenID 是一個去中心化的網上身份認證系統。對于支持 OpenID 的網站,用戶不需要記住像用戶名和密碼這樣的傳統驗證標記。取而代之的是,他們只需要預先在一個作為 OpenID 身份提供者(identity provider, IdP)的網站上注冊。OpenID 是去中心化的,任何網站都可以使用 OpenID 來作為用戶登錄的一種方式,任何網站也都可以作為 OpenID 身份提供者。OpenID 既解決了問題而又不需要依賴于中心性的網站來確認數字身份。

OpenID 相關基本術語:

  • 最終用戶(End User):想要向某個網站表明身份的人。
  • 標識(Identifier):最終用戶用以標識其身份的 URL 或 XRI。
  • 身份提供者(Identity Provider, IdP):提供 OpenID URL 或 XRI 注冊和驗證服務的服務提供者。
  • 依賴方(Relying Party, RP):想要對最終用戶的標識進行驗證的網站。

以上概念來自:https://zh.wikipedia.org/wiki/OpenID

針對 .NET Core 跨平臺,微軟官方并沒有針對 OAuth 2.0 的實現(Microsoft.AspNetCore.Authentication.OAuth組件,僅限客戶端),IdentityServer4 實現了 ASP.NET Core 下的 OpenID Connect 和 OAuth 2.0,IdentityServer4 也是微軟基金會成員。

閱讀目錄:

  • OpenID 和 OAuth 的區別
  • 客戶端模式(Client Credentials)
  • 密碼模式(resource owner password credentials)
  • 簡化模式-With OpenID(implicit grant type)
  • 簡化模式-With OpenID & OAuth(JS 客戶端調用)
  • 混合模式-With OpenID & OAuth(Hybrid Flow)
  • ASP.NET Core Identity and Using EntityFramework Core for configuration data

開源地址:https://github.com/yuezhongxin/IdentityServer4.Demo

1. OpenID 和 OAuth 的區別

簡單概括:

  • OpenID:authentication(認證),用戶是誰?
  • OAuth:authorization(授權),用戶能做什么?

其實,OAuth 的密碼授權模式和 OpenID 有些類似,但也不相同,比如用戶登錄落網選擇微博快捷登錄方式,大致的區別:

  • OAuth:用戶在微博授權頁面輸入微博的賬號和密碼,微博驗證成功之后,返回 access_token,然后落網拿到 access_token 之后,再去請求微博的用戶 API,微博授權中心驗證 access_token,如果驗證通過,則返回用戶 API 的請求數據給落網。
  • OpenID:落網可以沒有用戶的任何實現,落網需要確認一個 URL 標識(可以是多個),然后用戶登錄的時候,選擇一個 URL 進行登錄(比如微博),跳轉到微博 OpenID 登錄頁面,用戶輸入微博的賬號和密碼,微博驗證成功之后,按照用戶的選擇,返回用戶的一些信息。

可以看到,OAuth 首先需要拿到一個授權(access_token),然后再通過這個授權,去資源服務器(具體的 API),獲取想要的一些數據,上面示例中,用戶 API 只是資源服務器的一種(可以是視頻 API、文章 API 等等),在這個過程中,OAuth 最重要的就是獲取授權(四種模式),獲取到授權之后,你就可以通過這個授權,做授權范圍之類的任何事了。

而對于 OpenID 來說,授權和它沒任何關系,它只關心的是用戶,比如落網,可以不進行用戶的任何實現(具體體現就是數據庫沒有 User 表),然后使用支持 OpenID 的服務(比如微博),通過特定的 URL 標識(可以看作是 OpenID 標識),然后輸入提供服務的賬號和密碼,返回具體的用戶信息,對于落網來說,它關心的是用戶信息,僅此而已。

上面其實是 OAuth 的授權,所以會有“獲得以下權限”提示,如果是 OpenID 的話,“權限”應該改為“用戶信息”。

支持 OpenID 的服務列表:http://openid.net/get-an-openid/

OpenID 流程圖(來自 Using OpenID):

2. 客戶端模式(Client Credentials)

簡單概述:客戶端提供 ClientId 和 ClientSecret 給認證授權服務,驗證如果成功,返回 access_token,客戶端拿到 access_token,訪問 API 資源服務。

2.1 認證授權服務配置

創建 ASP.NET Core 站點,Startup 配置修改如下:

public class Startup {public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopesservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryApiResources(new List<ApiResource>{new ApiResource("api1", "My API")}).AddInMemoryClients(new List<Client>{// client credentials clientnew Client{ClientId = "client",AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},AllowedScopes = { "api1" }}});}public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){loggerFactory.AddConsole(LogLevel.Debug);app.UseDeveloperExceptionPage();app.UseIdentityServer();} }

IdentityServer4 中AddInMemory的相關配置,都是 Mock 的(代碼配置),也可以把這些配置存儲在數據庫中,這個后面再講。

AddInMemoryApiResources 增加的 API 資源服務(List 集合),也就此認證授權服務所管轄的 API 資源,比如上面配置的 api1,這個會在客戶端調用的時候用到,如果不一致,是不允許訪問的,另外,Clinet 中配置的AllowedScopes = { "api1" },表示此種授權模式允許的 API 資源集合(前提是需要添加ApiResource)。

配置很簡單,我們也可以訪問http://localhost:5000/.well-known/openid-configuration,查看具體的配置信息:

2.2 API 資源服務配置

API 資源服務站點,需要添加程序包:

"IdentityServer4.AccessTokenValidation": "1.0.1"

添加一個ValuesController:

[Route("[controller]")] [Authorize] public class ValuesController : ControllerBase {[HttpGet]public IActionResult Get(){return Content("hello world");} }

2.3 單元測試

需要添加程序包:

"IdentityModel": "2.0.0"

單元測試代碼:

[Fact] public async Task ClientCredentials_Test() {// request tokenvar disco = await DiscoveryClient.GetAsync("http://localhost:5000");var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");Assert.False(tokenResponse.IsError);Console.WriteLine(tokenResponse.Json);// call apivar client = new HttpClient();client.SetBearerToken(tokenResponse.AccessToken);var response = await client.GetAsync("http://localhost:5010/values");Assert.True(response.IsSuccessStatusCode);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content); }

很簡單,和我們之前用 ASP.NET WebApi OWIN 實現 OAuth 2.0 一樣,只不過配置和調用簡化了很多,因為 IdentityServer4 替我們做了很多工作。

3. 密碼模式(resource owner password credentials)

簡單概述:客戶端提供 UserName 和 Password 給認證授權服務,驗證如果成功,返回 access_token,客戶端拿到 access_token,訪問 API 資源服務。

3.1 認證授權服務配置

創建 ASP.NET Core 站點,Startup 配置修改如下:

public class Startup {public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopesservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryApiResources(new List<ApiResource>{new ApiResource("api1", "My API")}).AddInMemoryClients(new List<Client>{// resource owner password grant clientnew Client{ClientId = "ro.client",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,ClientSecrets ={new Secret("secret".Sha256())},AllowedScopes = { "api1" }}}).AddTestUsers(new List<TestUser>{new TestUser{SubjectId = "1",Username = "xishuai",Password = "123"}});}public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){loggerFactory.AddConsole(LogLevel.Debug);app.UseDeveloperExceptionPage();app.UseIdentityServer();} }

和客戶端模式不同的是,AllowedGrantTypes授權模式改為了ResourceOwnerPassword,然后增加了測試用戶(用來驗證用戶名和密碼),也可以存儲在數據庫中。

3.2 API 資源服務配置

API 資源服務站點,需要添加程序包:

"IdentityServer4.AccessTokenValidation": "1.0.1"

添加一個IdentityController:

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

3.3 單元測試

需要添加程序包:

"IdentityModel": "2.0.0"

單元測試代碼:

[Fact] public async Task ResourceOwnerPassword_Test() {// request tokenvar disco = await DiscoveryClient.GetAsync("http://localhost:5000");var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret");var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("xishuai", "123", "api1");Assert.False(tokenResponse.IsError);Console.WriteLine(tokenResponse.Json);// call apivar client = new HttpClient();client.SetBearerToken(tokenResponse.AccessToken);var response = await client.GetAsync("http://localhost:5010/identity");Assert.True(response.IsSuccessStatusCode);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(JArray.Parse(content)); }

4. 簡化模式-With OpenID(implicit grant type)

簡化模式在 IdentityServer4 中的實現,就是 OpenID Connect。

簡單概述:客戶端確定 URL(用戶認證服務),登錄在用戶認證服務,驗證成功,返回客戶端想要的用戶數據,并使此用戶為登錄狀態,可以在客戶端進行注銷用戶。

4.1 認證授權服務配置

創建 ASP.NET Core 站點,Startup 配置修改如下:

public class Startup {public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopesservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryIdentityResources(new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),}).AddInMemoryClients(new List<Client>{// OpenID Connect implicit flow client (MVC)new Client{ClientId = "mvc",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.Implicit,RedirectUris = { "http://localhost:5020/signin-oidc" },PostLogoutRedirectUris = { "http://localhost:5020" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile}}}).AddTestUsers(new List<TestUser>{new TestUser{SubjectId = "1",Username = "xishuai",Password = "123",Claims = new List<Claim>{new Claim("name", "xishuai"),new Claim("website", "http://xishuai.cnblogs.com")}}});}public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){loggerFactory.AddConsole(LogLevel.Debug);app.UseDeveloperExceptionPage();app.UseIdentityServer();} }

AddInMemoryIdentityResources和AllowedScopes所配置的,是客戶端允許訪問的用戶信息,具體查看:Requesting Claims using Scope Values

ClientId 很重要,必須和客戶端一一對應,所以想要使用 OpenID 認證服務的客戶端,需要向提供 OpenID 認證服務的機構,申請一個 ClientId,OpenID 認證服務會統一發放一個用戶登錄的 URL。

TestUser中的Claims配置,其實就是IdentityServerConstants.StandardScopes.Profile。

另外,還有用戶登錄的一些操作代碼,這邊就不貼了,可以查看具體的實現:ImplicitServer.Web

4.2 客戶端服務配置

創建 ASP.NET Core 站點,添加程序包:

"Microsoft.AspNetCore.Authentication.Cookies": "1.0.*", "Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.*"

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) {JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");}app.UseCookieAuthentication(new CookieAuthenticationOptions{AuthenticationScheme = "Cookies"});app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions{AuthenticationScheme = "oidc",SignInScheme = "Cookies",Authority = "http://localhost:5001",RequireHttpsMetadata = false,ClientId = "mvc",SaveTokens = true});app.UseStaticFiles();app.UseMvcWithDefaultRoute(); }

UseOpenIdConnectAuthentication配置中的Authority,就是 OpenID 認證服務的 URL。

添加一個HomeController:

public class HomeController : Controller {public IActionResult Index(){return View();}[Authorize]public IActionResult Secure(){ViewData["Message"] = "Secure page.";return View();}public async Task Logout(){await HttpContext.Authentication.SignOutAsync("Cookies");await HttpContext.Authentication.SignOutAsync("oidc");}public IActionResult Error(){return View();} }

訪問 Secure 頁面,跳轉到認證服務地址,進行賬號密碼登錄,Logout 用于用戶的注銷操作。

4.3 Web 測試

5. 簡化模式-With OpenID & OAuth(JS 客戶端調用)

簡單概述:客戶端確定 URL(用戶認證服務),登錄在用戶認證服務,驗證成功,返回客戶端想要的用戶數據 和 access_token,并使此用戶為登錄狀態,可以在客戶端進行注銷用戶,客戶端可以拿到 access_token,去訪問授權范圍之內的 API 資源。

需要注意的是:因為簡化模式,所以 access_token 是作為 URL 參數返回的。

5.1 認證授權服務配置

創建 ASP.NET Core 站點,Startup 配置修改如下:

public class Startup {public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopesservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryIdentityResources(new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),}).AddInMemoryApiResources(new List<ApiResource>{new ApiResource("api1", "My API")}).AddInMemoryClients(new List<Client>{// OpenID Connect implicit flow client (MVC)new Client{ClientId = "js",ClientName = "JavaScript Client",AllowedGrantTypes = GrantTypes.Implicit,AllowAccessTokensViaBrowser = true,RedirectUris = { "http://localhost:5022/callback.html" },PostLogoutRedirectUris = { "http://localhost:5022/index.html" },AllowedCorsOrigins = { "http://localhost:5022" },RequireConsent = false, //禁用 consent 頁面確認 https://github.com/IdentityServer/IdentityServer3/issues/863AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"}}}).AddTestUsers(new List<TestUser>{new TestUser{SubjectId = "1",Username = "xishuai",Password = "123",Claims = new List<Claim>{new Claim("name", "xishuai"),new Claim("website", "http://xishuai.cnblogs.com")}}});}public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){loggerFactory.AddConsole(LogLevel.Debug);app.UseDeveloperExceptionPage();app.UseIdentityServer();} }

因為涉及到訪問 API 資源操作,需要需要添加AddInMemoryApiResources配置,AllowedScopes也需要添加對應的 API 資源名稱,AllowAccessTokensViaBrowser = true的配置的作用就是,可以在瀏覽器地址中訪問 access_token。

更多實現代碼,點擊查看:ImplicitServerWithJS.Web

5.2 API 資源服務配置

API 資源服務站點,需要添加程序包:

"IdentityServer4.AccessTokenValidation": "1.0.1", "Microsoft.AspNetCore.Cors": "1.1.0"

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);builder.AddEnvironmentVariables();Configuration = builder.Build(); }public IConfigurationRoot Configuration { get; }public void ConfigureServices(IServiceCollection services) {services.AddCors(options =>{// this defines a CORS policy called "default"options.AddPolicy("default", policy =>{policy.WithOrigins("http://localhost:5022").AllowAnyHeader().AllowAnyMethod();});});services.AddMvcCore().AddAuthorization().AddJsonFormatters(); }public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) {loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();app.UseCors("default");app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions{Authority = "http://localhost:5003",RequireHttpsMetadata = false,ApiName = "api1"});app.UseMvc(); }

因為 JS 需要跨域訪問 API 資源服務,所以需要增加 CORS 配置。

添加一個IdentityController:

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

5.3 JS Web 站點測試

創建一個 ASP.NET Core 站點,添加oidc-client.js前端組件,測試 JS 代碼:

/// <reference path="oidc-client.js" />function log() {document.getElementById('results').innerText = '';Array.prototype.forEach.call(arguments, function (msg) {if (msg instanceof Error) {msg = "Error: " + msg.message;}else if (typeof msg !== 'string') {msg = JSON.stringify(msg, null, 2);}document.getElementById('results').innerHTML += msg + '\r\n';}); }document.getElementById("login").addEventListener("click", login, false); document.getElementById("api").addEventListener("click", api, false); document.getElementById("logout").addEventListener("click", logout, false);var config = {authority: "http://localhost:5003",client_id: "js",redirect_uri: "http://localhost:5022/callback.html",response_type: "id_token token",scope:"openid profile api1",post_logout_redirect_uri: "http://localhost:5022/index.html", }; var mgr = new Oidc.UserManager(config);mgr.getUser().then(function (user) {if (user) {log("User logged in", user.profile);}else {log("User not logged in");} });function login() {mgr.signinRedirect(); }function api() {mgr.getUser().then(function (user) {var url = "http://localhost:5012/identity";var xhr = new XMLHttpRequest();xhr.open("GET", url);xhr.onload = function () {log(xhr.status, JSON.parse(xhr.responseText));}xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);xhr.send();}); }function logout() {mgr.signoutRedirect(); }

測試過程(注意下 URL 中的參數):

6. 混合模式-With OpenID & OAuth(Hybrid Flow)

混合模式(Hybrid Flow)是一種新的模式,是簡化模式(implicit flow)和驗證碼模式(authorization code flow)的混合。

簡單概述:客戶端確定 URL(用戶認證服務),登錄在用戶認證服務,驗證成功,返回客戶端想要的用戶數據 和 access_token,并使此用戶為登錄狀態,可以在客戶端進行注銷用戶,客戶端可以拿到 access_token,去訪問授權范圍之內的 API 資源。

和上面的簡化模式流程差不多,不過 access_token 不是通過瀏覽器獲取的,而是通過后臺服務獲取。

6.1 認證授權服務配置

創建 ASP.NET Core 站點,Startup 配置修改如下:

public class Startup {public void ConfigureServices(IServiceCollection services){// configure identity server with in-memory stores, keys, clients and scopesservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryIdentityResources(new List<IdentityResource>{new IdentityResources.OpenId(),new IdentityResources.Profile(),}).AddInMemoryApiResources(new List<ApiResource>{new ApiResource("api1", "My API")}).AddInMemoryClients(new List<Client>{// OpenID Connect implicit flow client (MVC)new Client{ClientId = "mvc",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,ClientSecrets ={new Secret("secret".Sha256())},RedirectUris = { "http://localhost:5021/signin-oidc" },PostLogoutRedirectUris = { "http://localhost:5021" },AllowedScopes ={IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"api1"},AllowOfflineAccess = true}}).AddTestUsers(new List<TestUser>{new TestUser{SubjectId = "1",Username = "xishuai",Password = "123",Claims = new List<Claim>{new Claim("name", "xishuai"),new Claim("website", "http://xishuai.cnblogs.com")}}});}public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){loggerFactory.AddConsole(LogLevel.Debug);app.UseDeveloperExceptionPage();app.UseIdentityServer();} }

AllowedGrantTypes配置改為HybridAndClientCredentials,AllowOfflineAccess需要設置為true。

更多實現代碼,點擊查看:HybridServer.Web

6.2 API 資源服務配置

API 資源服務站點,需要添加程序包:

"IdentityServer4.AccessTokenValidation": "1.0.1"

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);builder.AddEnvironmentVariables();Configuration = builder.Build(); }public IConfigurationRoot Configuration { get; }public void ConfigureServices(IServiceCollection services) {services.AddMvcCore().AddAuthorization().AddJsonFormatters(); }public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) {loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions{Authority = "http://localhost:5002",RequireHttpsMetadata = false,ApiName = "api1"});app.UseMvc(); }

添加一個IdentityController:

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

6.3 客戶端服務配置

創建 ASP.NET Core 站點,添加程序包:

"Microsoft.AspNetCore.Authentication.Cookies": "1.0.*", "Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.*", "IdentityModel": "2.0.0"

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) {JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");}app.UseCookieAuthentication(new CookieAuthenticationOptions{AuthenticationScheme = "Cookies"});app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions{AuthenticationScheme = "oidc",SignInScheme = "Cookies",Authority = "http://localhost:5002",RequireHttpsMetadata = false,ClientId = "mvc",ClientSecret = "secret",ResponseType = "code id_token",Scope = { "api1", "offline_access" },GetClaimsFromUserInfoEndpoint = true,SaveTokens = true});app.UseStaticFiles();app.UseMvcWithDefaultRoute(); }

添加一個HomeController:

public class HomeController : Controller {public IActionResult Index(){return View();}[Authorize]public IActionResult Secure(){ViewData["Message"] = "Secure page.";return View();}public async Task Logout(){await HttpContext.Authentication.SignOutAsync("Cookies");await HttpContext.Authentication.SignOutAsync("oidc");}public IActionResult Error(){return View();}public async Task<IActionResult> CallApiUsingClientCredentials(){var tokenClient = new TokenClient("http://localhost:5002/connect/token", "mvc", "secret");var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");var client = new HttpClient();client.SetBearerToken(tokenResponse.AccessToken);var content = await client.GetStringAsync("http://localhost:5011/identity");ViewBag.Json = JArray.Parse(content).ToString();return View("json");}public async Task<IActionResult> CallApiUsingUserAccessToken(){var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");var client = new HttpClient();client.SetBearerToken(accessToken);var content = await client.GetStringAsync("http://localhost:5011/identity");ViewBag.Json = JArray.Parse(content).ToString();return Content("json");} }

CallApiUsingClientCredentials是通過客戶端模式獲取 access_token,CallApiUsingUserAccessToken是通過上下文獲取保存的 access_token,其實和瀏覽器 URL 中獲取是一樣的意思,但需要配置SaveTokens = true。

6.4 Web 測試

7. ASP.NET Core Identity and Using EntityFramework Core for configuration data

使用 ASP.NET Core Identity,就是用戶管理不由 OpenID 認證服務進行提供,ASP.NET Core Identity 就相當于用戶的一個管理者,比如用戶的存儲等。

我沒做這一塊的示例,配置比較簡單:

public void ConfigureServices(IServiceCollection services) {services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();services.AddMvc();services.AddTransient<IEmailSender, AuthMessageSender>();services.AddTransient<ISmsSender, AuthMessageSender>();// Adds IdentityServerservices.AddIdentityServer().AddTemporarySigningCredential().AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryApiResources(Config.GetApiResources()).AddInMemoryClients(Config.GetClients()).AddAspNetIdentity<ApplicationUser>(); }

詳細使用:Using ASP.NET Core Identity

關于 IdentityServer4 的配置信息,可以使用 EntityFramework Core 進行存儲,配置如下:

public void ConfigureServices(IServiceCollection services) {services.AddMvc();var connectionString = @"server=(localdb)\mssqllocaldb;database=IdentityServer4.Quickstart;trusted_connection=yes";var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;// configure identity server with in-memory users, but EF stores for clients and resourcesservices.AddIdentityServer().AddTemporarySigningCredential().AddTestUsers(Config.GetUsers()).AddConfigurationStore(builder =>builder.UseSqlServer(connectionString, options =>options.MigrationsAssembly(migrationsAssembly))).AddOperationalStore(builder =>builder.UseSqlServer(connectionString, options =>options.MigrationsAssembly(migrationsAssembly))); }

詳細使用:Using EntityFramework Core for configuration data


最后,簡要總結下使用 IdentityServer4 的幾種應用場景:

  • 客戶端模式(Client Credentials):和用戶無關,用于應用程序與 API 資源的直接交互場景。
  • 密碼模式(resource owner password credentials):和用戶有關,一般用于第三方登錄。
  • 簡化模式-With OpenID(implicit grant type):僅限 OpenID 認證服務,用于第三方用戶登錄及獲取用戶信息,不包含授權。
  • 簡化模式-With OpenID & OAuth(JS 客戶端調用):包含 OpenID 認證服務和 OAuth 授權,但只針對 JS 調用(URL 參數獲取),一般用于前端或無線端。
  • 混合模式-With OpenID & OAuth(Hybrid Flow):推薦使用,包含 OpenID 認證服務和 OAuth 授權,但針對的是后端服務調用。

開源地址:https://github.com/yuezhongxin/IdentityServer4.Demo

參考資料:

  • IdentityServer4
  • IdentityServer4.Samples
  • Welcome to IdentityServer4
  • Welcome to OpenID Connect
  • OpenID 學習筆記
  • OAuth 和 OpenID 的區別
  • OAuth、OAuth 與 OpenID 區別和聯系
  • 使用 OpenID、OAuth 和 Facebook Connect 武裝你的站點
  • OpenID Connect 身份認證標準推出,獲谷歌微軟支持

總結

以上是生活随笔為你收集整理的IdentityServer4 实现 OpenID Connect 和 OAuth 2.0的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一级黄大片 | 性欧美久久久 | 色伊人久久 | 精品爆乳一区二区三区无码av | 波多野吉衣在线观看视频 | 国产色在线观看 | 欧美人与性囗牲恔配 | 婷婷五月精品中文字幕 | 懂色av蜜臀av粉嫩av分 | 欧美多p | 天天干天天干 | 天天摸天天射 | 特黄级| 日韩av男人天堂 | 91精品一区二区三区在线观看 | 精品国产人妻一区二区三区 | 日韩av影音先锋 | 欧美高清视频一区 | 久操视频免费在线观看 | 日韩中文字幕视频 | 男人操女人的视频 | 一级片在线免费观看 | 9色视频| 天天舔天天干天天操 | 老熟妇一区二区三区啪啪 | 一区二区三区人妻 | 先锋av资源网站 | 欧美日韩一级二级 | 国产精品水嫩水嫩 | 一区二区网| 国产欧美日韩精品一区二区三区 | 人妻激情文学 | 天堂在线中文8 | 日韩免费观看一区二区 | 日韩一区二区三区在线 | 老女人毛片50一60岁 | 亚洲乱色熟女一区二区三区 | 北条麻妃二三区 | 秋霞精品| 激情五月综合 | 成人免费看片又大又黄 | 久久逼逼| 日韩美女视频一区二区 | 日韩国产欧美 | 日韩一级高清 | 日本一区二区三区视频在线观看 | 在线观看www视频 | 久久桃色| 亚洲精品成人片在线观看精品字幕 | 欧美午夜精品理论片 | 男女拍拍拍网站 | 午夜成人亚洲理伦片在线观看 | 中文一区二区在线播放 | 免费观看黄色av | 亚洲精选免费 | 久久久久久av无码免费网站下载 | 国产三级影院 | 毛片网在线 | 日本a在线免费观看 | 99r精品视频 | 国产美女主播在线观看 | 亚洲免费大片 | 黄色a一片| 中文字幕+乱码+中文乱码91 | 久视频在线 | 一女双乳被两男吸视频 | 国产chinesehd精品露脸 | www.青青草.com | 日日拍夜夜拍 | 国产午夜在线一区二区三区 | 永久免费AV无码网站韩国毛片 | 久久免费视频观看 | 91片黄在线观 | 波多野结衣在线免费观看视频 | 尤物在线观看视频 | 精品少妇久久 | 日屁网站 | 欧美性一区二区 | 亚洲精品中文字幕乱码三区 | 九九久久久 | 成年人黄色大全 | 日本久久激情 | 三级黄色在线视频 | 国产日韩综合 | 一区二区三区日韩 | 99爱精品视频 | 亚洲男人天堂2023 | 免费观看已满十八岁 | 亚洲一区二区日本 | 影音先锋在线看 | 最新视频–x99av | 亚洲一区二区三区播放 | 极品丰满少妇 | 18+视频在线观看 | 欧美一级视频免费观看 | 欧美女同在线 | 国产一区二区四区 | 日本在线免费 | 亚洲欧美婷婷 |