辅助工具

日志追踪包 : 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,验证结果即为最终结果

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

<调用结果>
{
"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. 配置ClientAllowedScopes值时要使用IdentityResourceName值,或者配置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. 如何使用Meter-WebSocketSampler

    安装 JMeter-WebSocketSampler 下载最新的 JMeter-WebSocketSampler,如 JMeterWebSocketSamplers-1.2.1.jar. 下载地址:h ...

  2. TOSCA自动化测试工具

    TOSCA由德国公司Tricentis研发,提供英文和德语两种版本. 目前他们的网上培训课程大约是2000一套,从初级到高级,从工程师到BA,有技术,也有测试管理. TOSCA的思想是,不用会编程的测 ...

  3. Qt5双缓冲机制与实例

    1. 双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上. 在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时会产生闪烁的现象, ...

  4. Java基础00-继承17

    1. 继承 1.1 继承概述 但是我们将相同的类提取出来就会变成这个样子 让他们之间产生一个继承的关系 1.2 继承的好处和弊端 IS-A.HAS-A和USE-A关系 苹果是水果的一种可以使用继承猫是 ...

  5. 自动执行文件夹中的py文件

    写一个函数,接收一个地址,执行其中的py文件,包括子文件.path.endswith('.py') 判断以'.py'结尾,是什么类型的文件.os.system('python %s'%path) 模拟 ...

  6. 队列Queue:任务间的消息读写,安排起来~

    摘要:本文通过分析鸿蒙轻内核队列模块的源码,掌握队列使用上的差异. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十三 消息队列Queue>,作者:zhushy . 队列(Queue)是 ...

  7. 使用宝塔配置laravel站点时,遇到open_basedir restriction in effect. 原因与解决方法

    今天一位朋友在linux服务器部署thinkphp5的时候PHP报了这个错误,如下: Warning: require(): open_basedir restriction in effect. F ...

  8. mysql为什么用b+树做索引

    关键字就是key的意思 一.B-Tree的性质 1.定义任意非叶子结点最多只有M个儿子,且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点的儿子数为[M/2, M]: ...

  9. IBM SPSS Statistics 26.0 Mac Windows Linux安装破解教程

    IBM SPSS Statistics 26.0是IBM公司推出的一款用于统计学分析运算.数据挖掘.预测分析和决策支持任务的软件产品及相关服务的程序. 下载 windows/mac/linux IBM ...

  10. Java 中节省 90% 时间的常用的工具类

    前言 你们有木有喜欢看代码的领导啊,我的领导就喜欢看我写的代码,有事没事就喜欢跟我探讨怎么写才最好,哈哈哈...挺好. 今天我们就一起来看看可以节省 90% 的加班时间的第三方开源库吧,第一个介绍的必 ...