C# GetRequest()返回null
作为问题的延续,我对dotnetopenauth有一些问题 我导航到依赖方代码并创建请求,但是当我的提供者收到请求时,C# GetRequest()返回null,c#,asp.net,.net,openid,dotnetopenauth,C#,Asp.net,.net,Openid,Dotnetopenauth,作为问题的延续,我对dotnetopenauth有一些问题 我导航到依赖方代码并创建请求,但是当我的提供者收到请求时,OpenIdProvider.GetRequest()返回null。我浏览了代码,据我所知,这是因为openid负载(request.form)不是由我的依赖方交付的;但我不明白为什么会这样 代码: 依赖方: public ActionResult Authenticate(string RuserName = "") { UriBuilder returnToBuilder =
OpenIdProvider.GetRequest()
返回null。我浏览了代码,据我所知,这是因为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)2)
提供者:
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日志说localhost不可信……但我将它添加到我的web.config中的白名单主机中,昨天它“工作正常”
编辑:好吧,这很奇怪。昨天,我通过DNOA来源试图找出问题所在。我启用了log4net,它创建了日志文件,并将其留空。今天我再次设置了log4net——它记录得很好,但我有一个错误,没有意义(见上文)。我也无法进入DNOA来源。我删除并重新添加了对dotnetopenauth.dll的引用,然后我与白名单主机之间的“原始错误”消失了,我能够进入源代码,但日志文件再次为空。我仍然有请求的问题。表单没有被填充
EDIT2:我的两个控制器都命名为“OpenIdController”(在RP和EP上)。我的RP在localhost:1903上运行,我的端点在localhost:3314上运行
EDIT3:在我做了更改后,您建议一切开始工作。RP可以很好地执行发现,但是当它实际发出请求时,我遇到了一个问题 行
IRequest i_request=OpenIdProvider.GetRequest()代码>工作正常,但当我尝试强制转换它时:IAuthenticationRequest iR=(IAuthenticationRequest)I\u 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()
用户代码未处理System.InvalidCastException
Message=无法将类型为“DotNetOpenAuth.OpenId.Provider.AutoResponsiveRequest”的对象强制转换为类型为“DotNetOpenAuth.OpenId.Provider.IAAuthenticationRequest”。
来源=门户
堆栈跟踪:
在Controllers\OpendIdController.cs中的Portal.Controllers.OpenIdController.Index()处:第35行
在lambda_方法中(闭包、控制器基、对象[])
位于System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller,Object[]参数)
位于System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext ControllerContext,IDictionary`2参数)
位于System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext ControllerContext,ActionDescriptor ActionDescriptor,IDictionary`2参数)
在System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass42.b__41()中
在System.Web.Mvc.Async.AsyncResultRapper.c_uuu显示类8`1.b_uuu7(IAsyncResult)
位于System.Web.Mvc.Async.AsyncResultRapper.WrappedAsyncResult`1.End()
位于System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
在System.Web.Mvc.Async.AsyncControllerActionInvoker.c_uuDisplayClass37.c_uuDisplayClass39.b_u33()中
在System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass4f.b__49()中
这段代码在我发现相关的两个示例之间有点像霍奇杂烩。我想设置一个SSO类型的环境,以便我使用的大部分代码来自\DotNetOpenAuth-4.1.0.12182\Samples\OpenIdWebRingSsoProvider\code\Util.cs
(ProcessAuthenticationChallenge函数)。但是,由于该函数需要一个IAuthenticationRequest
,但OpenIdProvider.GetRequest返回一个AutoResponsiveRequest
,因此我想我可以强制转换它,以便使用IAuthenticationRequest
类的属性和方法。显然我是错的
在这一点上,我不太确定如何处理事情。我应该使用OpenIdProviderMVC示例中的示例代码吗?关键的一点是,登录就像一个单一的登录一样工作,用户从来不会被提示输入OpenId。我也只会有一个端点(尽管我会有多个RP)
以下是指向最新RP日志的链接:
EDIT4:我按照你的建议做了,并取得了一些进展。我的EP接收到响应并尽可能地处理它,但当它重定向回领域url时,它会出错
012-10-10 13:55:01171(GMT-4)[25]错误DotNetOpenAuth.消息传递-协议错误:对域URL的HTTP请求(http://localhost:1903/)导致重定向,这在依赖方发现期间是不允许的。
领域
与返回到
相对的功能到底是什么?使用示例代码,领域最终是http://localhost:1903/
而ReturnTo最终是http://localhost:1903/OpenId/Authenticate
看起来不错。为什么EP需要向领域发出请求?我认为它应该在完成处理后将断言发送给returnTo。如果我手动将领域设置为http://localhost:1903/OpenId/Authenticate
然后relyingParty.GetResponse()
返回null
我的应用程序设置为在有人访问基本url时重定向(http://localhost:1903
)-我应该在那里运行什么代码来拦截DNOA EP请求
新日志:
RP:
EP:
我还更新了问题开头的代码,以更好地反映我所做的更改
EDIT5:领域必须是应用程序的实际基本URL吗?也就是说,(http://localhost:1903
)?考虑到现有的架构,很难删除重定向-我尝试将领域设置为基本OpenId控制器(<dotNetOpenAuth>
<messaging>
<untrustedWebRequest>
<whitelistHosts>
<add name="localhost" />
</whitelistHosts>
</untrustedWebRequest>
</messaging>
</dotNetOpenAuth>