作爲this問題的延續,我對dotnetopenauth存在問題。OpenIdProvider.GetRequest()返回null
我導航到我的依賴方代碼並創建請求,但是當我的提供程序收到請求時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)http://pastebin.com/Pnih3ND7 2)http://pastebin.com/eBzGun9y
提供者:http://pastebin.com/YAUTBzHk
有趣的是RP的日誌說,本地主機是不可信的......但我把它添加到我的web.config中的白名單的主機,它是「工作」昨天...
編輯:好的,這很奇怪。昨天我正在通過DNOA來源,試圖找出問題所在。我啓用了log4net,它創建了日誌文件並將其留空。今天我再次設置了log4net--它記錄的很好,但是我有一個沒有道理的錯誤(見上文)。我也無法步入DNOA來源。我刪除並重新添加了對dotnetopenauth.dll的引用,然後我的白名單主機的「原始錯誤」消失了,我能夠進入源代碼,但日誌文件又是空白的。我仍然有request.form沒有被填充的問題...
EDIT2:我的控制器都命名爲「OpenIdController」(RP和EP)。我的RP在localhost:1903上運行,我的端點在localhost:3314上運行。
EDIT3:以後,我所做的更改你的建議,事情開始工作。 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
EDIT4:我做了你的建議,並取得了一些進展。據我所知,我的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需要向領域提出請求?我一直認爲它應該只是在斷言完成處理後將斷言發送給returnTo。如果我手動將Realm設置爲http://localhost:1903/OpenId/Authenticate
,則relyingParty.GetResponse()
將返回null。
我有我的應用程序設置爲當有人訪問基地址(http://localhost:1903
)重定向 - 我應該運行哪些代碼來攔截DNOA EP請求?
新日誌:
RP:http://pastebin.com/L9K5Yft4
EP:http://pastebin.com/kBPWiUxp
我還更新了代碼在問題之初,以更好地反映我所做的更改。
EDIT5:請問領域必須是實際應用的基礎網址是什麼?那就是(http://localhost:1903
)?鑑於現有架構的原因,很難刪除重定向 - 我試圖將該領域設置爲基本OpenId控制器(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和OP收集日誌](http://tinyurl.com/dnoalogs)並將它們包括在您的問題中。 –
@AndrewArnott我試過了 - glimpse沒有起作用,log4net創建了日誌文件,但是留下了空白。我會盡力給它另一個鏡頭,雖然... – Mansfield
@AndrewArnott:得到了依賴方日誌,仍然在提供商工作。添加了OP的鏈接。 – Mansfield