この質問の続きとして、dotnetopenauthに問題があります。
証明書利用者コードに移動してリクエストを作成しましたが、プロバイダーがリクエストを受信すると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()
このコードは、私が関連性があると思った2つのサンプルの間のちょっとした寄せ集めです。SSOタイプの環境を設定したいので、使用しているコードの大部分は\DotNetOpenAuth-4.1.0.12182\Samples\OpenIdWebRingSsoProvider\Code\Util.cs
(ProcessAuthenticationChallenge関数)からのものです。ただし、その関数はIAuthenticationRequest
OpenIdProvider.GetRequestが返すことを期待しているため、クラスAutoResponsiveRequest
のプロパティとメソッドを使用するためにキャストできると考えました。IAuthenticationRequest
明らかに私は間違っていました。
現時点では、どうやってアプローチするのかよくわかりません。OpenIdProviderMVCサンプルのサンプルコードを使用する必要がありますか?重要なのは、ログインがシングルサインオンのように機能し、ユーザーが実際にOpenIdの入力を求められることはないということです。エンドポイントも1つだけです(ただし、複数の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
ですか?サンプルコードを使用すると、Realmが最終的に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: http: //pastebin.com/L9K5Yft4
EP: http: //pastebin.com/kBPWiUxp
また、質問の冒頭のコードを更新して、行った変更をより適切に反映させました。
EDIT5:レルムはアプリケーションの実際のベースURLである必要がありますか?つまり、(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.