0

動的データ Web サイトでロールを設定しようとしていますが、問題が発生しています。

ジェネリック プリンシパルで設定してから、既定のページにアクセスすると、プリンシパルの役割が失われます。プリンシパルは引き続き context.user としてリストされます。これは、セッションをデバッグして context.user オブジェクトを検査するときに、設定したユーザーが設定したユーザーであるためです。しかし、そのユーザーに関連するすべての役割が失われたようです。

これが私がそれについて行っている方法です。

ログインページ

public partial class Login : System.Web.UI.Page
{
    string[] masterServiceResult;

protected void btnSubmit_Click(object sender, EventArgs e)
{
    if (IsAuthenticUser(login_email.Text, login_password.Text))
    {
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, masterServiceResult[0], DateTime.Now, DateTime.Now.AddMinutes(30), false, masterServiceResult[2], FormsAuthentication.FormsCookiePath);
        string encryptedCookie = FormsAuthentication.Encrypt(ticket);
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
        Response.Cookies.Add(cookie);
        Response.Redirect(FormsAuthentication.GetRedirectUrl(masterServiceResult[0], true));

    }
}

private bool IsAuthenticUser(string email, string password)
{
    MembershipService membershipService = new MembershipService();
    var result = membershipService.GetUserAndRoleFromCredentials(email, password);

    //result is an array with userName, userId, error(bool) as string, and error message if any
    if (bool.Parse(result[3]) == false)
    {
        masterServiceResult = result;
        return true;
    }

    return false;
}
}

次に、Global.asax で AuthenticateRequest イベントにアタッチしました

void Global_AuthenticateRequest(object sender, EventArgs e)
{
    if (Request.IsAuthenticated)
        SetupRoles();
}

private void SetupRoles()
{
    if (Context.User != null)
    {
        string cookieName = FormsAuthentication.FormsCookieName;

        HttpCookie authCookie = Context.Request.Cookies[cookieName];

        if (authCookie == null)
            return;

        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        string[] roles = authTicket.UserData.Split(new char[] { '|' });

        IIdentity fi = Context.User.Identity;
        IPrincipal pi = new GenericPrincipal(fi, roles);


        Context.User = pi;

        //sets the application principal to use the logged on user account
        System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User;

        // sanity check to ensure the role was set up.
        if (User.IsInRole("Admin"))
        {
            int i = 0; // debug line
        }
    }
}

この時点で、すべてが意図したとおりに機能しています。テスト アカウントが context.user として設定され、現在のプリンシパル ユーザーが現在のユーザーとして設定され、管理者のユーザー ロールが原因で "int i=0" デバッグ行がヒットします。ただし、デフォルト ページの Page_Load がヒットすると、これはもはや当てはまりません。

デフォルトのページ。別のテスト ケースを示すために 01/03/12 を更新。protected void Page_Load(object sender, EventArgs e) { System.Collections.IList visibleTables = MetaModel.Default.VisibleTables;

    // this line comes back as false, though at this point the user name is the same.
    if (User.IsInRole("Admin"))
    {
        int i = 0;
    }

    // the next 4 lines of code is a work around I can do to retrieve the roles from the ticket.
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    // this line of code will correctly show the users role
    string[] roles = authTicket.UserData.Split(new char[] { '|' });

    foreach (var table in MetaModel.Default.Tables)
    {
        var permissions = ((MetaTable)table).GetTablePermissions(roles);
        if (permissions.Contains(TablePermissionsAttribute.Permissions.DenyRead))
            visibleTables.Remove(table);
    }

    if (visibleTables.Count == 0)
    {
        throw new InvalidOperationException("There are no accessible tables. Make sure that at least one data model is registered in Global.asax and scaffolding is enabled or implement custom pages.");
    }
    Menu1.DataSource = visibleTables;
    Menu1.DataBind();
}

*更新: 認証チケットからユーザーのロールを取得でき、プリンシパルは正しいのですが、User.IsInRole 行が失敗する理由がわかりません。

4

0 に答える 0