Как связать роль с пользователем в MVC 5? - PullRequest
0 голосов
/ 10 апреля 2019

В WebForms я использовал для хранения роли в пользовательских данных FormsAuthenticationTicket, однако я пытался реализовать тот же метод в MVC 5, и он не работал.По какой-то причине

User.Identity.IsAuthenticated

это возвращает false

var ticket = new FormsAuthenticationTicket(
    1,
    user.Id.ToString(),
    DateTime.Now,
    DateTime.Now.AddDays(5),
    model.RememberMe,
    user.Roles.Select(c => c.Nome).FirstOrDefault(),
    FormsAuthentication.FormsCookiePath
);

// Encrypt the ticket.
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); // Name of auth cookie (it's the name specified in web.config) // Hashed ticket
authenticationCookie.Expires = DateTime.Now.AddDays(7);
// Add the cookie to the list for outbound response
Response.Cookies.Add(authenticationCookie);

, так как это не работает, я использовал вместо

FormsAuthentication.SetAuthCookie(user.Id.ToString(), model.RememberMe);

проблема в том, что это непозвольте мне иметь легкий доступ к роли пользователя, чтобы я мог делать это в представлении

if (User.IsInRole("Admin"))

Я пытаюсь избежать Asp Net Identity, потому что это требует большой настройки и мне не нужновсе дополнительные поля и пароль, потому что мы аутентифицируемся с помощью ldap.

Если есть какие-либо другие варианты, пожалуйста, сообщите мне.

1 Ответ

0 голосов
/ 10 апреля 2019

Проверка подлинности с помощью форм не поддерживает роли сама по себе.Таким образом, вам нужно установить запрос IPrincipal с ролями вручную .Вы можете сделать это, подписавшись на событие post authenticate в Global.asax и обновив информацию о зарегистрированном пользователе.Добавьте следующий метод внутри MvcApplication класса в Global.asax.cs

protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (authCookie != null)
    {
        //get the forms authentication ticket
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        string userData = authTicket.UserData;
        //here we suppose userData contains roles joined with ","
        string[] roles = userData.Split(',');

        //at this point we already have Context.User set by forms authentication module
        //we don't change it but add roles
        var principal = new GenericPrincipal(Context.User.Identity, roles);

        // set new principal with roles
        Context.User = principal;
    }
}

Также вам необходимо обновить код для входа в систему, чтобы создать правильный FormsAuthenticationTicket содержащий роли, соединенные с ","

var roles = user.Roles.Select(c => c.Nome);
var ticket = new FormsAuthenticationTicket(
    1,
    user.Id.ToString(),
    DateTime.Now,
    DateTime.Now.AddDays(5),
    model.RememberMe,
    string.Join(",", roles), //or you can serialize complex class as json or whatever
    FormsAuthentication.FormsCookiePath
);

Другой вариант - переопределить аутентификацию форм , добавив метод FormsAuthentication_OnAuthenticate в Global.asax.cs

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
    if (FormsAuthentication.CookiesSupported)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            try
            {
                //get the forms authentication ticket
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                string userData = authTicket.UserData;
                //here we suppose userData contains roles joined with ","
                string[] roles = userData.Split(',');

                //we have to create identity since it's not created yet
                var identity = new FormsIdentity(authTicket);
                var principal = new GenericPrincipal(identity, roles);

                args.User = principal;
            }
            catch (Exception e)
            {
                // Decrypt method failed.
            }
        }
    }
    else
    {
        throw new HttpException("Cookieless Forms Authentication is not " +
                                "supported for this application.");
    }
}

Оба решения очень похожи, поэтому вы можете выбрать одно.

...