gpt4 book ai didi

c# - OpenIdProvider.GetRequest() 返回 null

转载 作者:行者123 更新时间:2023-11-30 22:24:54 25 4
gpt4 key购买 nike

作为 this 的延续问题,我在使用 dotnetopenauth 时遇到了问题。

我导航到我的信赖方代码并创建请求,但是当我的提供者收到请求时 OpenIdProvider.GetRequest()返回空值。我查看了代码,据我所知,这是因为我的依赖方没有提供 openid 有效负载(request.form);但我不明白这是为什么。

代码:

依赖方:

public ActionResult Authenticate(string RuserName = "")
{
UriBuilder returnToBuilder = new UriBuilder(Request.Url);
returnToBuilder.Path = "/OpenId/Authenticate";
returnToBuilder.Query = null;
returnToBuilder.Fragment = null;

Uri returnTo = returnToBuilder.Uri;
returnToBuilder.Path = "/";
Realm realm = returnToBuilder.Uri;

var response = openid.GetResponse();

if (response == null) {
if (Request.QueryString["ReturnUrl"] != null && User.Identity.IsAuthenticated) {

} else {

string strIdentifier = "http://localhost:3314/User/Identity/" + RuserName;
var request = openid.CreateRequest(
strIdentifier,
realm,
returnTo);

var fetchRequest = new FetchRequest();
request.AddExtension(fetchRequest);
request.RedirectToProvider();
}
} else {
switch (response.Status) {
case AuthenticationStatus.Canceled:
break;
case AuthenticationStatus.Failed:
break;
case AuthenticationStatus.Authenticated:
//log the user in
break;
}
}

return new EmptyResult();

}

供应商:
public ActionResult Index()
{
IRequest request = OpenIdProvider.GetRequest();

if (request != null) {
if (request.IsResponseReady) {
return OpenIdProvider.PrepareResponse(request).AsActionResult();
}

ProviderEndpoint.PendingRequest = (IHostProcessedRequest)request;
return this.ProcessAuthRequest();
} else {
//user stumbled on openid endpoint - 404 maybe?
return new EmptyResult();
}
}

public ActionResult ProcessAuthRequest()
{
if (ProviderEndpoint.PendingRequest == null) {
//there is no pending request
return new EmptyResult();
}

ActionResult response;
if (this.AutoRespondIfPossible(out response)) {
return response;
}

if (ProviderEndpoint.PendingRequest.Immediate) {
return this.SendAssertion();
}

return new EmptyResult();
}

日志:

RP: 1) http://pastebin.com/Pnih3ND7 2) http://pastebin.com/eBzGun9y

提供商: http://pastebin.com/YAUTBzHk

有趣的是,RP 日志说 localhost 是不受信任的……但是我将它添加到我的 web.config 中的白名单主机中,昨天它“工作”了……

编辑:好的,这很奇怪。昨天我正在逐步浏览 DNOA 来源,试图找出问题所在。我启用了 log4net,它创建了日志文件并将其留空。今天我再次设置了 log4net - 它记录得很好,但我有一个没有意义的错误(见上文)。我也无法进入 DNOA 源。我删除并重新添加了对 dotnetopenauth.dll 的引用,然后我与列入白名单的主机的“原始错误”消失了,我能够进入源代码,但日志文件又是空白的。而且我仍然遇到 request.form 没有填充的问题......

编辑2 :我的两个 Controller 都被命名为“OpenIdController”(在 RP 和 EP 上)。我的 RP 在 localhost:1903 上运行,而我的端点在 localhost:3314 上运行。

编辑3 :在我进行更改后,您建议的事情开始起作用了。 RP 可以很好地执行发现,但是当它实际发出请求时我遇到了问题。

线路 IRequest i_request = OpenIdProvider.GetRequest();工作正常,但是当我尝试转换时: IAuthenticationRequest iR = (IAuthenticationRequest)i_request;它给了我以下错误:
 System.InvalidCastException was unhandled by user code
Message=Unable to cast object of type 'DotNetOpenAuth.OpenId.Provider.AutoResponsiveRequest' to type 'DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest'.
Source=Portal
StackTrace:
at Portal.Controllers.OpenIdController.Index() in Controllers\OpendIdController.cs:line 35
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()

这段代码有点像我发现相关的两个样本之间的大杂烩。我想设置一个 SSO 类型的环境,所以我使用的大部分代码来自 \DotNetOpenAuth-4.1.0.12182\Samples\OpenIdWebRingSsoProvider\Code\Util.cs (ProcessAuthenticationChallenge 函数)。但是,由于该函数需要 IAuthenticationRequest但 OpenIdProvider.GetRequest 返回 AutoResponsiveRequest我想我可以强制转换它以使用 IAuthenticationRequest 的属性和方法。类。显然我是错误的。

在这一点上,我不太确定如何处理事情。我应该使用 OpenIdProviderMVC 示例中的示例代码吗?关键是登录像单点登录一样工作,并且实际上从未提示用户输入 OpenId。我也只会有一个端点(尽管我会有多个 RP)。

这是最新 RP 日志的链接: http://pastebin.com/enpwYqq3

编辑4 : 我按照你的建议做了,并取得了一些进展。据我所知,我的 EP 收到响应并对其进行处理,但是当它重定向回领域 url 时,它会出错。
012-10-10 13:55:01,171 (GMT-4) [25] ERROR DotNetOpenAuth.Messaging - Protocol error: An HTTP request to the realm URL (http://localhost:1903/) resulted in a redirect, which is not allowed during relying party discovery. Realm的功能究竟是什么?与 ReturnTo 相反?使用示例代码,领域最终是 http://localhost:1903/而 ReturnTo 最终是 http://localhost:1903/OpenId/Authenticate这似乎很好。为什么EP需要向realm发起请求?我原以为它应该只是在完成处理后将断言发送到 returnTo 。如果我手动将 Realm 设置为 http://localhost:1903/OpenId/Authenticate然后 relyingParty.GetResponse()返回空值。

我确实将我的应用程序设置为在有人访问基本 url ( http://localhost:1903 ) 时进行重定向 - 我应该在那里运行什么代码来拦截 DNOA EP 请求?

新日志:

RP: http://pastebin.com/L9K5Yft4

EP: http://pastebin.com/kBPWiUxp

我还更新了问题开头的代码,以更好地反射(reflect)我所做的更改。

编辑5 :领域是否必须是应用程序的实际基本 URL?也就是说,( http://localhost:1903 )?鉴于现有的体系结构,很难删除重定向 - 我尝试将领域设置为基本 OpenId Controller ( http://localhost:1903/OpenId ),手动测试确实生成了 XRDS 文档。但是,应用程序似乎卡住了,EP 日志显示以下错误:
2012-10-10 15:17:46,000 (GMT-4) [24] ERROR DotNetOpenAuth.OpenId - Attribute Exchange extension did not provide any aliases in the if_available or required lists.

最佳答案

你的 RP 有非常可疑的奇怪代码。虽然 return_to 和领域具有相同的 Uri 权限是正常的(实际上是必需的),但事实上,您将用户提供的标识符作为第一个参数传递给 OpenIdRelyingParty.CreateRequest与您的依赖方具有相同的主机和端口非常奇怪。通常,您传入的标识符是提供商托管的 URL。现在,我不知道端口 3314 是您的 RP 还是您的 OP,但无论如何,您的 RP 代码中的这些端口号之一看起来是错误的。

其次,对用户标识符的发现因空引用异常而失败(根据您的 RP 日志的 v2)。这将阻止登录请求到达您的提供者。您的 Provider 被调用但 OpenID 请求不存在这一事实表明 http://localhost:3314/OpenId/实际上是您的 OP 端点(读取 OpenID 请求的 OpenID 提供程序的操作方法的 URL)。那将是不合适的。您应该传递给您的 OpenIdRelyingParty.CreateRequest 的 URL同样,方法的第一个参数应该是用户的 OpenID URL——而不是 OP 端点。查看 OpenIdProviderMvc 示例的用户 Controller ,了解如何设置用户 OpenID URL 的示例。然后使用该 URL 作为 CreateRequest 的第一个参数我认为你会很好。

第三,一旦您的 Provider 收到非空请求,您就不能总是将其强制转换为 IAuthenticationRequest .并非所有 OpenID 消息都是身份验证消息。有些是底层 OpenID 协议(protocol)的一部分。如果您查看 OpenIdProviderMvc 示例的 OpenID Controller ,您应该注意到有条件转换来处理不同的消息类型。您应该在 Controller 中进行类似的消息处理。

由于您要使用 SSO 方案,因此您的 Controller 的显着差异大概是:

  • 您的 Controller 永远不会响应重定向到登录页面,而是“神奇地”找出用户是谁。
  • 您的 Controller 应该检查 IAuthenticationRequest.Realm属性反对包含在您的 SSO 网络环中的 RP 白名单,并且仅在领域符合条件时提供肯定断言。这可以减轻攻击,一旦您的服务器设置好,任何人都可以设置一个站点,该站点悄悄地使用您的 OpenID 提供程序来识别随机 Internet 网站的用户(如果他们属于您的组织),这会侵犯他们的隐私。

  • 第四,OP 发送到您 RP 的“领域”URL 的 HTTP 请求是 OpenID 调用“RP 发现”过程的一部分。它可以减轻“开放重定向器”攻击。您应该将 RP 的基本 URL 调整为不重定向,而是在 RP 发现请求进来时返回 XRDS 文档。您仍然可以针对正常浏览器情况进行重定向。您可以在 OpenIdRelyingPartyMvc 示例的 HomeController 中查看如何执行此操作的示例。

    关于c# - OpenIdProvider.GetRequest() 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12517083/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com