1

asp.net webforms の Web サイトに奇妙な問題があります。フォーム認証と mysql バックエンドを使用して vs2008 で開発されました。開発システム(win7)および5月の実稼働サーバーで正常に動作します。

新しい 2008 R2 サーバーでは、その動作は奇妙です。ログイン ページからログインすると、デフォルト ページに正しくリダイレ​​クトされますが、ユーザー メニューは生成されません。しかし、アプリ プールをリサイクルしてページを更新すると、メニューが表示され、後で問題なく動作します。また、ログアウトしてログインすると、再び同じ問題が発生し、アプリ プールがリサイクルされるまでメニューが表示されません。

ログから、DB から値を取得していないようです。データがあっても。httpcontext の適切なユーザー名が表示され、ユーザーが認証されていることが示されます。また、ログ、イベントログなどにエラーは表示されません。

ここで何が起こっているのかわかりません。

アップデート :

ログに log4net とログ情報を使用しています。コードに何か問題がある可能性があります。

ここでweb.configの一部

  <connectionStrings>
   <add name="tmsConnectionString" connectionString="server=localhost;user id=root;password=54545;persist security info=false;database=tms;port=3306;convert zero datetime=yes;Allow Zero Datetime=True" providerName="MySql.Data.MySqlClient" />
    <add name="archiveConnectionString" connectionString="server=localhost;user id=root;password=55645;database=archive;persist security info=True;port=3306;convert zero datetime=yes;Allow Zero Datetime=True" providerName="MySql.Data.MySqlClient" />
  </connectionStrings>
  <system.web>
    <roleManager enabled="true" cookieName=".ASPROLES" defaultProvider="MySqlRoleProvider" cacheRolesInCookie="false">
      <providers>
        <clear />
        <add connectionStringName="tmsConnectionString" applicationName="tms" writeExceptionsToEventLog="true" name="MySqlRoleProvider" type="Andri.Web.MySqlRoleProvider" />
      </providers>
    </roleManager>
    <membership defaultProvider="MySqlMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear />
        <add name="MySqlMembershipProvider" type="Andri.Web.MySqlMembershipProvider" connectionStringName="tmsConnectionString" applicationName="tms" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" writeExceptionsToEventLog="true" />
      </providers>
    </membership>
    <authentication mode="Forms">
      <forms name=".ASPXFORMSAUTH" slidingExpiration="false" loginUrl="~/login.aspx" defaultUrl="~/default.aspx" path="/" protection="All" cookieless="AutoDetect" timeout="180" />
    </authentication>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>

こちらがデフォルトページのページロードです。

     protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            log.Debug("User - " + Page.User.Identity.Name);
            log.Debug("User IsAuthenticated- " + Page.User.Identity.IsAuthenticated.ToString());
            log.Debug("User AuthenticatedType- " + Page.User.Identity.AuthenticationType);

            if (Page.User.IsInRole(Tms.Constants.Roles.Administrator))
            {
                log.Debug("role: Administrator");
                ASPxMenu1.Items[0].Visible = true;
            }
            else if (Page.User.IsInRole(Tms.Constants.Roles.Manager))
            {
                log.Debug("role: Manager");
                ASPxMenu1.Items[1].Visible = true;
            }
            else {
                log.Debug("Menu not created - Role not supported");
            }
        }
    }

メンバーシップロールマネージャーを使用して、ユーザーがロールにいるかどうかを確認するコードは次のとおりです

    public static bool IsInRole(this IPrincipal User, Tms.Constants.Roles roletype)
    {
        string role = roletype.ToString().ToLower();
        log.DebugFormat("IsInRole role: {0}", role.ToLower());
        log.DebugFormat("IsInRole user: {0}", User.Identity.Name);

        return User.IsInRole(role.ToLower());
    }

ここにログがあります

INFO 2012-06-17 LoginPage Login1_LoggedIn - ログイン: 管理者
DEBUG 2012-06-17 DefaultPage Page_Load - ユーザー - 管理者
DEBUG 2012-06-17 DefaultPage Page_Load - ユーザー IsAuthenticated - True
DEBUG 2012-06-17 DefaultPage Page_Load - ユーザー認証タイプ - フォーム
INFO 2012-06-17 ユーザー IsInRole - IsInRole ロール: 管理者
INFO 2012-06-17 ユーザー IsInRole - IsInRole ユーザー: 管理者
INFO 2012-06-17 ユーザー IsInRole - IsInRole ロール: マネージャー
INFO 2012-06-17 ユーザー IsInRole - IsInRole ユーザー: 管理者
DEBUG 2012-06-17 DefaultPage Page_Load - メニューが作成されていません - ロールがサポートされていません

ユーザー「管理者」としてログインすると、メニューが作成されていません。「管理者」はロール管理者ですが。

奇妙なことに、メンバーシップ プロバイダー「User.IsInRole」の代わりに、カスタム ロジックを使用してユーザー情報を取得すると、DB はまだ値を返しません。元:

    static public int GetUserId(string name)
    {
        log.DebugFormat("UserIdFromUsername({0})", name);

        using (var TA = new Tms.DataAccessTableAdapters.usersTableAdapter())
        {
            log.DebugFormat("connection({0})", TA.Connection.ConnectionString);

            var usertable = TA.GetDataBy_Username(name);

            log.DebugFormat("count({0})", usertable.Rows.Count.ToString());
            if (usertable.Rows.Count>0)
            {
                return usertable[0].Id;
            }
            else { return 0; }
        }
    }

それのログ

DEBUG 2012-06-17 ユーザー GetUserId - UserIdFromUsername(admin)
DEBUG 2012-06-17 User GetUserId - connection(server=localhost;user id=root;password=54545;persist security info=false;database=tms;port=3306;convert zero datetime=yes;Allow Zero Datetime=True)
DEBUG 2012-06-17 ユーザー GetUserId - count(0)

したがって、そのユーザーがDBに存在していても、ユーザー情報は返されません。

IIS アプリ プールをリサイクルしてページを更新するだけで、両方のケースですべてが機能し始めます。つまり、メンバーシップ プロバイダーまたはカスタム ロジックを意味します。ログアウトするまでです。再度ログインしても同じ問題。

アプリ レベルでエラー ログが記録されますが、エラーはありません。IIS 関連サービスから、これに関連するシステム イベント ログにエラーまたはメッセージはありません。

4

1 に答える 1

0

これは、構成の問題ではなく、コードのバグのように思えます (もちろん、コードが構成について想定しているため、問題が発生する可能性があります)。ロギング フレームワーク (log4net など、独自の単純な FileStream ベースのロガーをロールする) を使用し、ページ/コントローラーの実行中の重要なポイントでプログラムの状態に関する詳細をロガーに書き込み、後でそれらを検査することをお勧めします。あなたが得ることができるリモートデバッグを取得します。

最善の解決策は、VS リモート デバッグ ツールをインストールし、問題が発生しているサーバーに接続することですが、ドメイン間の信頼と認証の問題に対処する必要がある場合は、これが問題になる可能性があります (DCOM はMDM とリモート デバッグの主要な部分であり、解決するのに時間がかかる問題が発生する可能性があります (単なる警告です)。

アップデート:

ログを投稿していただきありがとうございます。ログに書き込むときに .ToLower() を実行しているようです。大文字と小文字の区別の問題により、IsInRole 関数が望ましくない動作をしているのだろうかと思います。SQL 文字列の比較では大文字と小文字が区別されませんが、C# では大文字と小文字が区別されることに注意してください。

于 2012-06-17T20:09:39.037 に答える