辅助工具

日志追踪包 : Serilog.AspNetCore

源码查看工具 : ILSpy

项目环境 ###:

ASP.NetCore 3.1

IdentityServer4 4.0.0+

主题内容

测试登录方式 : password

错误内容:

connect/token 登陆出错

但百度/google网上的示例没有找到正确的调用方式,无奈只能自己动手,丰衣足食...

首先,先按照之前版本进行传参

  • POST请求
  • url: connect/token
  • 参数传递通过 form-data

调用结果:

<调用结果>
HTTP : 400 {
"error": "invalid_request"
}

查找调用日志

Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token

可以看到地址匹配是成功的,那就是校验不通过了,接着看一下这个类的源码,找到错误触发地

public async Task<IEndpointResult> ProcessAsync(HttpContext context)
{
if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasApplicationFormContentType())
{
return Error("invalid_request");
}
}

此处有两个验证:

  1. POST请求 √
  2. HasApplicationFormContentType ?

查看方法定义:

internal static bool HasApplicationFormContentType(this HttpRequest request)
{
if (request.ContentType == null)
{
return false;
}
if (MediaTypeHeaderValue.TryParse(request.ContentType, out MediaTypeHeaderValue parsedValue))
{
return parsedValue.MediaType.Equals("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase);
}
return false;
}

... 好样的,最新版改用了application/x-www-form-urlencoded传参

然后改一下传参方式接着调用:

<调用结果>
HTTP : 400 {
"error": "invalid_scope"
}

换了个错误,至少说明传参改动还是有效的...

查找操作日志:

IdentityServer4.Validation.TokenRequestValidator
No scopes found in request

key code:

string text = parameters.Get("scope");

if (text.IsMissing())
{
text = clientAllowedScopes.Distinct().ToSpaceSeparatedString();
}
List<string> requestedScopes = text.ParseScopesString();
if (requestedScopes == null)
{
LogError("No scopes found in request");
return false;
}

scope取值:

如果没有传值,就去client中取

public static List<string> ParseScopesString(this string scopes)
{
if (scopes.IsMissing())
{
return null;
}
scopes = scopes.Trim();
List<string> list = scopes.Split(new char[1]
{
' '
}, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();
if (list.Any())
{
list.Sort();
return list;
}
return null;
}

如果有传值 就用传值的获取,多个scope用' '分隔

在配置中,是有AllowedScopes配置,但取不出来? 先不管,用传值方式先试试...

<调用结果>
HTTP : 400 {
"error": "invalid_scope"
}

??? 再查下日志:

IdentityServer4.Validation.DefaultResourceValidator

Scope api1 not found in store.

还好错误变了,不然没得玩了...

先确认配置信息:

return new List<ApiResource>
{
new ApiResource("api1", "My API")
};

是有这个api1的,好吧,只能再去查看源码了

DefaultResourceValidator Scope验证分析

IdentityResource identity = resourcesFromStore.FindIdentityResourcesByScope(requestedScope.ParsedName);
if (identity != null)
{
if (await IsClientAllowedIdentityResourceAsync(client, identity))
{
result.ParsedScopes.Add(requestedScope);
result.Resources.IdentityResources.Add(identity);
}
else
{
result.InvalidScopes.Add(requestedScope.RawValue);
}
return;
}

首先先通过name去拿IdentityResource,拿到了IdentityResource验证结果即为最终结果

ApiScope apiScope = resourcesFromStore.FindApiScope(requestedScope.ParsedName);

没有拿到IdentityResource则再通过name去拿ApiScope,验证结果即为最终结果

把IdentityResource的Name值配置到Client中的AllowedScopes去,然后再在传参里使用IdentityResource的Name值

<调用结果>
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjUyM0EzMjE0Q0M4MzAzQjJBRDA2Mzk5N0E2RDI1NDEyIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE1OTQxMTAwNjcsImV4cCI6MTU5NDExMzY2NywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiY2xpZW50X2lkIjoicm8uY2xpZW50Iiwic3ViIjoiMiIsImF1dGhfdGltZSI6MTU5NDExMDA2NywiaWRwIjoibG9jYWwiLCJqdGkiOiJCMEY1NEI2NDI1QzUwRDU2REVEMjBGQUY0QkMwNTE5MiIsImlhdCI6MTU5NDExMDA2Nywic2NvcGUiOlsib3BlbmlkIl0sImFtciI6WyJwd2QiXX0.PqYMwqHfZ3CHtE8q_eCi5H1FVCPKe01uSPiSTNjV0q1m61s98OQezo9M3FCc4bGTw4c6VruylSQAbtT6sid2nYXV05Eq_fD_4KKPTya6NLuTdwgdUohzNN10f3SC0ea1nDhv_94Ewkov_9OWrCSLxAX9yVFKDDs6dB3V53_49n4-3Hd9BkCOevWk-_FzpkMOOhYMi-5LNeZRAXH3G5_GZ7INtypCUx2f0_v84UzQxx2LjcovzAy0ZR3GgFvAh5rgRwd5oBVeiLZOt2ZjvV0b5NAtPSbiEcufFK5box6qm_q2M6GrrMBUm0aTTTd3Vu6Zx-pjjITHQN934EICRKWYFg",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "openid"
}

over... 总算通了


总结

  1. 传参需要使用 application/x-www-form-urlencoded
  2. 配置Client的AllowedScopes值时要使用IdentityResource的Name值,或者配置ApiScope
  3. 传参传scope时,通过制指定scope进行验证,未传时通过配置的信息(AllowedScopes)进行验证

新版的ApiResource作用

待补充...

配置参考

public static class Config
{
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "1",
Username = "alice",
Password = "password"
},
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "password"
}
};
} public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId()
};
} public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client", // no interactive user, use the clientid/secret for authentication
AllowedGrantTypes = GrantTypes.ClientCredentials, // secret for authentication
ClientSecrets =
{
new Secret("secret".Sha256())
}, // scopes that client has access to
AllowedScopes = { "api1" }
},
// resource owner password grant client
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "openid" }
}
};
}
} public void ConfigureServices(IServiceCollection services)
{ var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers()); builder.AddDeveloperSigningCredential(); } // 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();
} app.UseIdentityServer(); }

ASP.Net Core Web Api 使用 IdentityServer4 最新版 踩坑记录的更多相关文章

  1. .net core 微服务架构-docker的部署-包括网关服务(Ocelot)+认证服务(IdentityServer4)+应用服务(asp.net core web api)

    本文主要介绍通过Docker来部署通过.Net Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发).统一认证(IdentityServer4).应用服务(asp.net c ...

  2. 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)

    对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...

  3. 在ASP.NET Core Web API上使用Swagger提供API文档

    我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的API文档功能.当设置IISExpress的默认启动路由到Swagger的API文档页 ...

  4. Docker容器环境下ASP.NET Core Web API应用程序的调试

    本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...

  5. 在docker中运行ASP.NET Core Web API应用程序

    本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...

  6. ASP.NET Core Web API Cassandra CRUD 操作

    在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...

  7. 在Mac下创建ASP.NET Core Web API

    在Mac下创建ASP.NET Core Web API 这系列文章是参考了.NET Core文档和源码,可能有人要问,直接看官方的英文文档不就可以了吗,为什么还要写这些文章呢? 原因如下: 官方文档涉 ...

  8. ASP.NET Core Web API 开发-RESTful API实现

    ASP.NET Core Web API 开发-RESTful API实现 REST 介绍: 符合REST设计风格的Web API称为RESTful API. 具象状态传输(英文:Representa ...

  9. Docker容器环境下ASP.NET Core Web API

    Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...

随机推荐

  1. Linux常用命令 day day up

    一.Shell二.Linux命令的分类1.查看内部命令2.禁用内部命令三.Linux命令行格式四.编辑Linux命令行的辅助操作五.获得命令帮助的方法1.pwd--查看当前的工作目录2.cd--切换工 ...

  2. W: GPG 错误:http://mirrors.aliyun.com xenial/mongodb-org/3.2 Release: 由于没有公钥,无法验证下列签名: NO_PUBKEY D68FA50FEA312927

    更新错误: 正在读取软件包列表... 完成 W: GPG 错误:http://mirrors.aliyun.com xenial/mongodb-org/3.2 Release: 由于没有公钥,无法验 ...

  3. 高性能内存图数据库RedisGraph(二)

    这篇文章主要介绍用一下RedisGraph的历史和现状. 2018年5月,Redis Labs发布了RedisGraph的预览/测试版.6个月后,在Redis Labs和开源社区的开发者们的共同努力下 ...

  4. C# BS方向 该如何规划学习?【学习路线指南】

    C#学习路线指南 花费了几天时间整理了C#学习路线图,可以说是纯野生C#程序员成长路线规划,在这里分享下,希望可以帮助到想从事C#开发的同学们.本人阅历尚浅,有些知识点可能分享不正确,希望广大网友评论 ...

  5. 小师妹学IO系列文章集合-附PDF下载

    目录 第一章 IO的本质 IO的本质 DMA和虚拟地址空间 IO的分类 IO和NIO的区别 总结 第二章 try with和它的底层原理 简介 IO关闭的问题 使用try with resource ...

  6. 在java中为啥要重写toString 方法?

    在java中为啥要重写toString 方法?下面以一个简单的例子来说明. 先定义一个test5类.并写它的get,set方法. package test5; public class Test5 { ...

  7. 解决proto文件生成pb文件时提示(e.g."message")的问题

    原因:格式不支持 解决办法:去下个notepad,打开方式选择notepad,文件属性的只读取消掉 打开后会发现最下面显示了文件的格式是unix,utf-8 右键红框处,选择转换为windows格式, ...

  8. Maven之--安装nexus 私服

    开始搜索下载了,nexus3.19版本,下来之后,建立一个maven 骨架过程 quickstart,提示没有lgf4j依赖和和maven插件都没有,开始搜索什么原因,猜想是nexus没有索引,右搜索 ...

  9. HCNA Routing&Switching之交换技术基础

    什么是交换机?顾名思义,交换机就是用来数据包交换的:广泛用于终端接入:它的前身是hub(集线器),hub是一个古老的设备,它的作用也是用于终端接入,但hub有一个最大的缺点是它不能隔离冲突域:所谓冲突 ...

  10. xshell中操作服务器笔记

    sudo su 获取root权限 cd 切换到相应文件夹 ll ls 查看文件夹内容 cp file folder 复制文件到文件夹 \cp为强制覆盖不提示 cp -r /packageA/* /cp ...