1

HttpModule を使用して、多言語サイトの URL を書き換えています。HttpModule では、BeginRequest イベントのハンドラーを追加し、カルチャ名を含むパスの最初の部分を探しています。

たとえば、/fr-ca/index.aspx は /index.aspx に書き換えられ、スレッドのカルチャと ui カルチャが 3084 に設定されます。これは正常に機能します。

フォーム認証を入力します。フォーム認証はマップされていない URL でも正常に機能しますが、ユーザーが承認されていない場合は、web.config の認証セクションで設定されている loginUrl にリダイレクトされ、要求された URL へのリダイレクトを処理するために ?ReturnUrl= クエリ文字列パラメーターが含まれます。ユーザーが認証されると、ページ。

ユーザーがデフォルト以外の言語でページを要求した場合、ここで 2 つの問題があります。

  1. loginUrl は、書き換えられる前にパスを無視します
  2. ReturnUrl パラメーターも生のパスを無視していました。

Request.RawUrl の代わりに Request.Url.PathAndQuery に相当します。

代わりに、AuthorizeRequest イベントでパイプラインにジャンプすることはできません。これは、複数の場所のパスを持つ 1 つの web.config ファイルを使用しているため、考えられるすべてのカルチャ値から保護する必要があるためです。これも最初の問題を修正しません。

リフレクターで FormsAuthenticationModule を調べたところ、#1 と #2 を解決するためにどこを変更できるかがわかりますが、もちろん封印されています。

私もたくさん閲覧しましたが、実行可能な解決策は見当たりません。

FormsAuthenticationModule は、UrlAuthorizationModule で生成された 401 ヘッダーをチェックしています。loginUrl ページでリファラー (空) を探すと、それが確認されます。

何かご意見は?

編集#1

IIS 6 を使用していますが、IIS 7 はオプションではありません。

編集#2

ローカル リソースを生成したときに (デザイン ビュー: [ツール] > [ローカル リソースの生成])、IDE がページ ディレクティブに以下を追加したため、ログイン ページは既定のカルチャ/UI カルチャを取得しませんでした。

culture="auto" meta:resourcekey="PageResource1" uiculture="auto"

vs.net 2008 ではこれに注意してください。少なくともこれにより、デフォルトのカルチャが参照されないという問題の 1 つが解決されますが、#1 と #2 はまだ未解決です。

編集3

パイプライン イベントの 1 つにジャンプして独自のリダイレクトを実行できることを望んでいましたが、System.Web.Security.UrlAuthorizationModule OnEnter メソッドの反映で、401 ヘッダーが設定されると、メソッドが application.CompleteRequest を呼び出すことがわかりました。お察しのとおり、EndRequest イベントに進みます。これは、FA モジュールがリダイレクトを実行するためにジャンプするものです。残念ながら、自分のリダイレクトを実行するために前にジャンプすることはできません! この問題に遭遇する人がこれ以上いないことに驚いています。


例:

フォーム認証によって保護されている物理フォルダー /members/ にメンバーのセクションがあります。

web.config には、次のものがあります。

<authentication mode="Forms">
  <forms loginUrl="~/members/login.aspx" timeout="40" />
</authentication>

と...

  <location path="members">
      <system.web>
          <authorization>
              <deny users="?" />
              <allow roles="Members" />
              <deny users="*" />
          </authorization>
      </system.web>
  </location>

認証されていないユーザーが /members/ のインデックス ページを要求すると、FormsAuthenticationModule によって上記の認証セクションから loginUrl にリダイレクトされます。また、要求されたページに ?ReturnUrl パラメーターを追加します。

これは、ユーザーが既定のカルチャを使用して Web サイトを閲覧している場合に問題なく機能しますが、私の HttpModule は、パスの最初の部分にあるカルチャ名の存在に基づいてカルチャを設定します。

そのため、/fr-ca/members/index.aspx は /members/index.aspx に書き換えられ、カルチャ/UI カルチャがカナダ フランス語に設定されます。残念ながら、FormsAuthenticationModule は、元の URL ではなく、書き換えられた URL を使用して loginUrl ページにユーザーを送信します。そのため、カルチャ設定が失われ、リダイレクト URL が正しくありません。

@グレッグに役立つことを願っています

4

2 に答える 2

3

わかりました、問題は解決しました。

キーは、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
于 2009-08-01T17:35:25.690 に答える
1

私が考えることができる唯一のことは、ログインフォームへのリダイレクトを手動で行うことです。

1) メンバーシップ ディレクトリへのすべてのアクセスを許可する
2) メンバーシップ内のすべてのページは、Page のサブクラスから直接継承します。
3) Page サブクラスの PreInit(?) で、ユーザーがメンバーシップ ロールのメンバーであるかどうかを確認します。
4) そうでない場合は、ReturnURL パラメータを含むログイン ページの URL を自分で作成し、ユーザーをログイン URL にリダイレクトします。

web.config に多数の <location> セクションを配置することで、これをハッキングすることもできます。例: < location path="fr-ca/members">< 認証>< フォーム loginUrl="~/fr-ca/members/login.aspx">...しかし、私にはまったくわかりません。

私がよく知らない他の方法があるかもしれません。

于 2009-07-31T19:04:10.057 に答える