ASP.NetOAuthAuthorizationServer:AddanArrayasanAdditionalResponseParameter当客户端请求访问时,在响应中添加一些额外的元素令牌。为此,我覆盖了OAuthAuthorizationServerProvider.TokenEndpoint方法并成功地添加了一些单独的元素(通过将它们添加到context.AdditionalResponseParameters字典)。现在我有这样的回应:{“access_token”:“wxoCtLSdPXNW9KK09PVhSqYho...”,“token_type”:“bearer”,“expires_in”:1199,“refresh_token”:“uk0kFyj4Q2OufWKt4IzWQHlj...”,“toto”:“bloblo”,"tata":"blabla"}这很好,但我的目标是添加一个数组来获得这种响应:{"access_token":"wxoCtLSdPXNW9KK09PVhSqYho...","token_type":"bearer","expires_in":1199,"refresh_token":"uk0kFyj4Q2OufWKt4IzWQHlj...","scopes":["read","write"]}我试图添加一个json解析列表或数组而不是一个简单的字符串,但它给了我"scopes":"["read","write"]"这是解析为Json的字符串,而不是Json数组:/如何在TokenEndpoint响应中添加Json数组?问题当我们使用app.OAuthBearerAuthenticationExtensions时,下一个链被调用:.Use((object)typeof(OAuthBearerAuthenticationMiddleware),(object)app,(object)options);app.UseStageMarker(PipelineStage.Authe通知);返回应用程序;OAuthAuthorizationServerMiddleware类型的对象然后使用内部类OAuthAuthorizationServerHandler,它使用JsonTextWriter:)记忆;jsonTextWriter.WritePropertyName("access_token");jsonTextWriter.WriteValue(accessToken);jsonTextWriter.WritePropertyName("token_type");jsonTextWriter.WriteValue("承载");//依此类推this.Response.ContentLength=newlong?((long)body.Length);等待this.Response.WriteAsync(body,this.Request.CallCancelled);这里有两个限制:*)JsonTextWriter是一个纯类,不能配置,它只是将字符串写成StringBuilder,所以Json.Settings=newMySettings()不能应用JsontTextWriter也不支持复杂对象。数组只能用jsonTextWriter.WriteStartArray()和jsonTextWriter.WriteEndArray()写入,但在OAuthAuthorizationServerHandler中会被忽略。*)有些类是内部的,不能被覆盖或继承。微软的开发人员似乎没有预见到这个问题,只是将自定义属性限制在IDictionary中。解决方案1而不是app.UseOAuthBearerAuthentication(...)应用您自己的代码app.Use(options);app.UseStageMarker(PipelineStage.Authenticate);您可以从OAuthBearerAuthenticationMiddleware派生一个类并将其用于您自己的目的。解决方案2覆盖令牌端点响应。这是一件棘手的事情。1)创建一个自定义中间件,它将包装其他调用并覆盖Body响应流。类AuthenticationPermissionsMiddleware:OwinMiddleware{publicAuthenticationPermissionsMiddleware(OwinMiddlewarenext):base(next){}publicoverrideasyncTaskInvoke(IOwinContextcontext){if(!context.Request.Path.Equals("/Token"){awaitNext.Invoke(context);return;}using(vartokenBodyStream=newMemoryStream()){//保存初始OWIN流varinitialOwinBodyStream=context.Response.Body;//创建新的内存流context.Response.Body=tokenBodyStream;//其他中间件将更新我们的tokenBodyStreamawaitNext.Invoke(context);vartokenResponseBody=GetBodyFromStream(context.Response);varobj=JsonConvert.DeserializeObject(tokenResponseBody);varjObject=JObject.FromObject(obj);//添加自定义数组或任何其他对象varscopes=newScope[];jObject.Add("scopes",JToken.FromObject(scopes));varbytes=Encoding.UTF8.GetBytes(jObject.ToString());context.Response.Body.Seek(0,SeekOrigin.Begin);awaittokenBodyStream.WriteAsync(bytes,0,bytes.Length);context.Response.ContentLength=data.LongLength;tokenBodyStream.Seek(0,SeekOrigin.Begin);//将结果返回到OWIN流awaitcontext.Response.Body.CopyToAsync(initialOwinBodyStream);}}}privatestringGetBodyFromStream(IOwinResponseresponse){使用(varmemoryStream=newMemoryStream()){response.Body.Seek(0,SeekOrigin.Begin);response.Body.CopyTo(memoryStream);memoryStream.Seek(0,SeekOrigin.Begin);使用(varreader=newStreamReader(memoryStream)){returnreader.ReadToEnd();}}}}2)以上是在认证启动方法中使用UseOAuthBearerTokens之前的新中间件C#学习教程:ASP.NetOAuthAuthorizationServer:添加一个数组作为额外的响应参数,共享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注—app.Use();app.UseOAuthBearerTokens(选项);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
