ローカライズのための.net URLの書き換え、フォーム認証およびloginUrlの問題
-
06-07-2019 - |
質問
HttpModuleを使用して、多言語サイトのURLを書き換えています。 HttpModuleでは、BeginRequestイベントのハンドラーを追加し、カルチャ名を含むパスの最初の部分を探しています。
たとえば、/ fr-ca / index.aspxは/index.aspxに書き換えられ、スレッドのカルチャとUIカルチャを3084に設定します。これは正常に機能します。
フォーム認証を入力します。フォーム認証はマップされていないURLでも引き続き機能しますが、ユーザーが承認されていない場合、web.configの認証セクションで設定されているloginUrlにリダイレクトし、?ReturnUrl = querystringパラメーターを含めて、要求されたURLユーザーが認証されるとページが表示されます。
ユーザーがデフォルト以外の言語でページをリクエストした場合、2つの問題があります。
- loginUrlは、書き換えられる前のパスを無視します
- ReturnUrlパラメーターも生のパスを無視しました。
Request.RawUrlではなくRequest.Url.PathAndQueryと同等です。
代わりにAuthorizeRequestイベントでパイプラインにジャンプできません。複数のロケーションパスを持つ1つのweb.configファイルを使用しているため、考えられるすべてのカルチャ値から保護する必要があるためです。これでも最初の問題は解決しません。
リフレクターでFormsAuthenticationModuleを確認し、#1と#2を解決するためにどこで変更できるかを確認しましたが、もちろん封印されています。
多くのことも閲覧しましたが、実行可能な解決策が見つかりません。
FormsAuthenticationModuleは、UrlAuthorizationModuleで生成された401ヘッダーをチェックしています。 loginUrlページでリファラー(空)を検索すると、それが確認されます。
何か考えはありますか
編集#1
IIS 6を使用していますが、IIS 7はオプションではありません。
編集#2
ローカルリソース(デザインビュー:ツール<!> gt;ローカルリソースの生成)を生成したときに、IDEがページディレクティブに以下を追加したため、ログインページでデフォルトのカルチャ/ UIカルチャが選択されませんでした:
culture = <!> quot; auto <!> quot; meta:resourcekey = <!> quot; PageResource1 <!> quot; uiculture = <!> quot; auto <!> quot;
vs.net 2008ではこれに注意してください!少なくともこれにより、デフォルトカルチャが参照されないという問題の1つが解決されますが、#1と#2は未解決のままです。
編集3
パイプラインイベントの1つにジャンプして独自のリダイレクトを行うことを望んでいましたが、System.Web.Security.UrlAuthorizationModule OnEnterメソッドのリフレクトでは、401ヘッダーが設定されると、メソッドがアプリケーションを呼び出すことを学びました。 CompleteRequestは、ご想像のとおり、EndRequestイベントに至ります。これは、FAモジュールがジャンプしてリダイレクトを行うものであり、自分でリダイレクトを行うために前にジャンプすることはできないと思います!この問題に出くわす人がこれ以上いないか、あるいはまだ気づいていないことに驚いています。
例:
フォーム認証によって保護されている物理フォルダー/ members /にメンバーのセクションがあります。
web.configには、次のものがあります:
<authentication mode="Forms">
<forms loginUrl="~/members/login.aspx" timeout="40" />
</authentication>
and ...
<location path="members">
<system.web>
<authorization>
<deny users="?" />
<allow roles="Members" />
<deny users="*" />
</authorization>
</system.web>
</location>
認証されていないユーザーが/ members /のインデックスページをリクエストすると、FormsAuthenticationModuleによって上記の認証セクションからloginUrlにリダイレクトされます。また、要求されたページに?ReturnUrlパラメーターを追加します。
ユーザーがデフォルトのカルチャを使用してウェブサイトを閲覧している場合、これは問題なく機能しますが、私のHttpModuleはパスの最初の部分のカルチャ名の存在に基づいてカルチャを設定します。
したがって、/ fr-ca / members / index.aspxは/members/index.aspxに書き換えられ、culture / ui文化をカナダのフランス語に設定します。残念ながら、FormsAuthenticationModuleはユーザーを元のURLではなく、書き換えられたURLでloginUrlページに送信します。そのため、カルチャ設定が失われ、リダイレクトURLが正しくありません。
希望@Gregを支援します
解決
OK、問題は解決しました。
鍵は、machine.config httpModulesをクリアし、カスタムhttpModuleを追加してから、必要なデフォルトhttpModulesを追加し直すことでした。これにより、カスタムhttpModuleはFormsAuthenticationHttpModuleの前にEndRequestイベントにジャンプできました。
<httpModules>
<clear/>
<!-- custom -->
<add name="LocalizationHttpModule" type="LocalizationHttpModule"/>
<!-- add back defaults, exlude PassportAuthentication, AnonymousIdentification, Profile -->
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
</httpModules>
次に、カスタムhttpModuleでEndRequestをタップし、401ステータスコードを探して、必要に応じてリダイレクトします。基本的には、FormsAuthenticationHttpModule OnLeaveメソッドのコードを自分のニーズに合わせて書き換えています。
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
Dim authentication As AuthenticationSection = WebConfigurationManager.GetSection("system.web/authentication")
If authentication.Mode = AuthenticationMode.Forms Then
Me._LoginUrl = authentication.Forms.LoginUrl
AddHandler context.EndRequest, AddressOf Context_EndRequest
End If
End Sub
Private Sub Context_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim application As HttpApplication = DirectCast(sender, HttpApplication)
Dim context As HttpContext = application.Context
If (context.Response.StatusCode = &H191) Then
' do custom redirect here
End If
End Sub
他のヒント
考えられる唯一のことは、ログインフォームへのリダイレクトを手動で行うことです。
1)メンバーシップディレクトリへのすべてのアクセスを許可
2)メンバーシップのすべてのページは、Pageのサブクラスから直接継承します。
3)PageサブクラスのPreInit(?)で、ユーザーがメンバーシップロールのメンバーであるかどうかを確認します。
4)そうでない場合は、ReturnURLパラメーターを含むログインページのURLを自分で作成し、ユーザーをログインURLにリダイレクトします。
<!> lt;を束ねてこれをハッキングすることもできます。ロケーション<!> gt; web.configのセクション。例:<!> lt; location path = <!> quot; fr-ca / members <!> quot; <!> gt; <!> lt;認証<!> gt; <!> lt;フォームloginUrl = <!> quot;〜/ fr-ca / members / login.aspx <!> quot; <!> gt; ...しかし、私には本当にわからない。
おそらく私がよく知らない他の方法があります。