ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

IdentityServer4之Resource Owner Password Credentials(资源拥有者密码凭据许可)

2022-04-22 23:04:42  阅读:194  来源: 互联网

标签:Resource var 添加 localhost Owner new options IdentityServer4 客户端


IdentityServer4之Resource Owner Password Credentials(资源拥有者密码凭据许可)

前言

IdentityServer4简称IDS4,是为ASP.NET Core系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证框架。

允许一个客户端发送用户名和密码到令牌服务并获得一个表示该用户的访问令牌,就是我们通常所说的access_token。

该规范建议仅对“受信任”应用程序使用资源所有者密码授权。 一般来说,当您要验证用户并请求访问令牌时,通常使用交互式OpenID Connect流会更好,在IdentityServer中可以快速引入用户。

环境

Visual Studio 2019 + .net 5.0

IdentityServer4 (4.0.0)

Microsoft.AspNetCore.Authentication.JwtBearer (5.0.0)

IdentityModel (6.0.0)

实现步骤

创建IDS4项目

dotnet CLI快速安装模板Identityserver模板

dotnet new -i IdentityServer4.Templates

创建IdentityServery 项目

dotnet new is4empty -n IdentityServer_ResourceOwnerPasswordCredentials

注意项目名不可以取IdentityServery 4,不然会和IdentityServery 4.Dll引用重名。

引用IdentityServer4依赖

这里使用4.0.0版本,如图:

修改端口

此模板中使用的协议是https,在 Kestrel 上运行时端口设置为 5001 或在 IISExpress 上运行时设置为随机端口。可以在Properties\launchSettings.json文件中更改它。

{

  "profiles": {

​    "SelfHost": {

​      "commandName": "Project",

​      "launchBrowser": true,

​      "environmentVariables": {

​        "ASPNETCORE_ENVIRONMENT": "Development"

​      },

​      "applicationUrl": "https://localhost:5001;http://localhost:5000"

​    }

  }

}

这里修改为:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

定义API接口的活动范围****API Scope

API 是系统中要保护的资源。资源定义可以通过多种方式加载。模板已经创建了 Config.cs。打开它,将代码更新为如下所示:

public static IEnumerable<ApiScope> ApiScopes =>

​            new ApiScope[]

​            { new ApiScope("api1", "My API")};

添加用户

就像基于内存存储的资源(即范围 Scopes)和客户端一样,对于用户也可以这样做。

TestUser类型表示一个测试用户及其身份信息。 Config.cs文件中添加以下代码以创建用户:


public static List GetUsers()

​ {

​ return new List

​ {

​ new TestUser

​ {

​ SubjectId = "1",

​ Username = "alice",

​ Password = "password"

​ },

​ new TestUser

​ {

​ SubjectId = "2",

​ Username = "bob",

​ Password = "password"

​ },

​ new TestUser

​ {

​ SubjectId = "3",

​ Username = "yak",

​ Password = "yakpassword"

​ }

​ };

​ }

配置身份服务器

在Startup文件中配置身份服务器,加载资源和客户端,然后将测试用户注册到 IdentityServer中。代码如下:

public void ConfigureServices(IServiceCollection services)

​ {

​ var builder = services.AddIdentityServer()

​ .AddInMemoryIdentityResources(Config.GetIdentityResources())

​ .AddInMemoryApiScopes(Config.ApiScopes)

​ .AddInMemoryClients(Config.GetClients())

​ .AddTestUsers(Config.GetUsers());

​ builder.AddDeveloperSigningCredential();

​ }

AddTestUsers扩展方法在背后做了以下几件事:

(1)为资源所有者密码授权添加支持

(2)添加对用户相关服务的支持,这服务通常为登录 UI 所使用

(3)为基于测试用户的身份信息服务添加支持

添加客户端****定义

可以通过修改AllowedGrantTypes属性简单地添加对已有客户端授权类型的支持。

通常要为资源所有者用例创建独立的客户端,添加以下代码到你配置中的客户端定义中

public static IEnumerable GetClients()

​ {

​ return new List

​ {

​ // resource owner password grant client

​ new Client

​ {

​ ClientId = "yakclient",

​ AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,

​ ClientSecrets =

​ {

​ new Secret("yaksecret".Sha256())

​ },

​ AllowedScopes = { "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile }//需要额外添加

​ }

​ };

​ }

项目生成后会生成jwk加密文件,如图:

使用Postman测试工具测试

调用接口后返回access_token,测试结果如下

grant_type password
client_id yakclient
client_secret yaksecret
username yak
password yakpassword

新建WebAPI接口

新建接口,命名为Api,同时引用依赖:

Microsoft.AspNetCore.Authentication.JwtBearer.dll

注册认证相关组件和配置

在Startup.cs文件中修改ConfigureServices方法,代码如下:

public void ConfigureServices(IServiceCollection services)

​ {

​ services.AddControllers();

​ // 注册认证相关组件和配置defaultScheme为Bearer

​ services.AddAuthentication("Bearer")

​ .AddJwtBearer("Bearer", options =>

​ {

​ options.Authority = "http://localhost:5000";

​ // 在验证token时,不验证Audience

​ options.TokenValidationParameters = new TokenValidationParameters

​ {

​ ValidateAudience = false

​ };

​ options.RequireHttpsMetadata = false; // 不适用Https

​ });

​ services.AddAuthorization(options =>

​ {

​ options.AddPolicy("api1Scope", policy =>

​ {

​ policy.RequireAuthenticatedUser();

​ policy.RequireClaim("scope", "api1");

​ });

​ });

​ }

注意Configure方法中添加认证和授权

app.UseAuthentication();

app.UseAuthorization();

新建测试客户端

新建一个WinForm客户端,添加按钮及引用IdentityModel依赖,这里使用6.0.0版本。

按钮事件代码如下:

private void button1_Click(object sender, EventArgs e)

​ {

​ Task.FromResult(MainAsync());

​ }

​ private async Task MainAsync()

​ {

​ // discover endpoints from metadata

​ var client = new HttpClient();

​ var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");

​ if (disco.IsError)

​ {

​ textBox1.Text = disco.Error;

​ return;

​ }

​ textBox2.Text = disco.TokenEndpoint + "\r\n";

​ // request token

​ var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest

​ {

​ Address = disco.TokenEndpoint,

​ ClientId = "yakclient",

​ ClientSecret = "yaksecret",

​ UserName = "yak",

​ Password = "yakpassword",

​ Scope = "api1"

​ });

​ if (tokenResponse.IsError)

​ {

​ textBox1.Text = tokenResponse.Error;

​ return;

​ }

​ textBox2.Text += tokenResponse.Json.ToString();

​ // call api

​ var apiClient = new HttpClient();

​ apiClient.SetBearerToken(tokenResponse.AccessToken);

​ var response = await apiClient.GetAsync("http://localhost:4571/weatherforecast");

​ if (!response.IsSuccessStatusCode)

​ {

​ textBox1.Text += response.StatusCode.ToString();

​ }

​ else

​ {

​ var content = response.Content.ReadAsStringAsync().Result;

​ textBox1.Text += content;

​ }

​ }

启动程序

启动多个程序项目,注意IdentityServer_ResourceOwnerPasswordCredentials项目先启动。

测试结果如下

使用Postman测试如下:

总结

本想写简单点,可是不知不觉写了好多,因为在做的过程中可能很小的细节就可能导致项目运行不了,为了方便大家了解,还是尽可能详细吧!读者照着步骤做,印象会更深。

鸣谢

https://www.cnblogs.com/stulzq/p/7509648.html#top

http://www.identityserver.com.cn/Home/Detail/shiyongmimabaohuapi

https://identityserver4.readthedocs.io/en/latest/endpoints/authorize.html

源码

https://github.com/yandaniugithub/NETCore

img

标签:Resource,var,添加,localhost,Owner,new,options,IdentityServer4,客户端
来源: https://www.cnblogs.com/yakniu/p/16180878.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有