3

.NET 2.0 のカスタム ロール プロバイダー (RoleProvider から継承) では、IsUserInRole メソッドは常に true を返すようにハードコードされています。

public override bool IsUserInRole(string username, string roleName) { return true; }

このロール プロバイダーを使用するように構成された ASP.NET アプリケーションでは、次のコードは (予想どおり) true を返します。

Roles.IsUserInRole("any username", "any rolename"); // results in true

ただし、次のコードは false を返します。

Roles.IsUserInRole("any rolename"); // results in false

User.IsInRole("any rolename") も false を返すことに注意してください。

  1. これは予想される動作ですか?
  2. ロール名のみを受け取るオーバーロードが、オーバーライドされた IsUserInRole を呼び出すと仮定するのは間違っていますか?

更新:単一の文字列を取るバージョンで使用できるオーバーライドがないように見えることに注意してください。

4

3 に答える 3

3

.net リフレクターで Roles.IsUserInRole(string rolename) を調べたところ、次のように解決されました。

public static bool IsUserInRole(string roleName)
{
    return IsUserInRole(GetCurrentUserName(), roleName);
}

現在のユーザーを見てみましょう。理由は次のとおりです。

private static string GetCurrentUserName()
{
    IPrincipal currentUser = GetCurrentUser();
    if ((currentUser != null) && (currentUser.Identity != null))
    {
        return currentUser.Identity.Name;
    }
    return string.Empty;
}

現在のユーザーを持っていないか、その名前が空の文字列またはnullであるため、これが空の文字列を返していると確信しています。

このIsUserInRole(string username, string roleName)メソッドには、最初のすぐ近くに次のコード ブロックがあります。

   if (username.Length < 1)
   {
       return false;
   }

GetCurrentUserName()意味のあるものを何も返さない場合は、オーバーライドされたメソッドを呼び出す前に false を返します。

これから取るべき教訓: リフレクターは素晴らしいツールです :)

于 2008-12-12T14:59:44.340 に答える
0

RoleManager 設定で cacheRolesInCookie="true" を選択した場合も注意してください。データベースに新しいロールを追加した場合、Cookie にキャッシュされたバージョンを参照している可能性があります。

私はこの問題を抱えていましたが、解決策は Cookie を削除して再ログインすることでした。

于 2009-12-07T14:17:33.467 に答える
0

これは誰かを助けるかもしれません-注意してください:

認証にログイン コントロールを使用している場合、コントロールに入力されたユーザー名は、Roles.IsUserInRole(string rolename) で使用される HttpContext.Current.User.Identity.Name になり、具体的にはメンバーシップの GetUser() メソッドで使用されます。その場合は、Authenticate イベントをオーバーライドし、このメソッドでユーザーを検証し、カスタム メンバーシップ プロバイダーが使用できる値にユーザー名を設定してください。

 protected void crtlLoginUserLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
    bool blnAuthenticate = false;
    string strUserName = crtlLoginUserLogin.UserName;

    if (IsValidEmail(strUserName))
    {

        //if more than one user has email address - must authenticate by username.

        MembershipUserCollection users = Membership.FindUsersByEmail(strUserName);
        if (users.Count > 1)
        {
            crtlLoginUserLogin.FailureText = "We are unable to determine which account is registered to that email address. Please enter your Username to login.";

        }
        else
        {
            strUserName = Membership.GetUserNameByEmail(strUserName);
            blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);

            //setting the userLogin to the correct user name (only on successful authentication)
            if (blnAuthenticate)
            {
                crtlLoginUserLogin.UserName = strUserName;
            }

        }


    }
    else
    {
        blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
    }

    e.Authenticated = blnAuthenticate;

}
于 2010-03-25T12:36:01.717 に答える