Подтвердить что ты не робот

Объединить использование аутентификации как для страниц MVC, так и для страниц веб-API?

У меня есть веб-приложение MVC 5 и вы можете войти на страницу Login.cshtml и получить файл cookie, и логин работает нормально. Но я хотел бы сделать логин с веб-API, а затем (возможно) установить файл cookie, чтобы я зарегистрировался на своих страницах MVC... (или войдите в систему с помощью входа в MVC и затем подключился к веб-API), однако web api возвращает токен-носитель, а не токен cookie... так что это не работает. Есть ли способ объединить использование аутентификации как для моих страниц MVC, так и для моих страниц веб-API?

UPDATE:

Это не проблема кода, а скорее концептуальная проблема.

Обычные веб-страницы MVC исследуют файл cookie с именем, по умолчанию, ".AspNet.ApplicationCookie", чтобы определить идентификатор запросов. Этот файл cookie генерируется вызовом ApplicationSignInManager.PasswordSignInAsync.

С другой стороны, вызовы WebAPI проверяют заголовки запросов для элемента с именем Authorization... и используют это значение для определения идентификатора запроса. Это возвращается из вызова WebAPI в "/Token".

Это очень разные значения. Мой веб-сайт должен использовать как страницы MVC, так и вызовы WebAPI (для динамического обновления этих страниц)... и оба должны быть аутентифицированы для выполнения своих задач.

Единственный метод, о котором я могу думать, - это фактически дважды аутентифицировать... один раз с вызовом WebAPI и снова с сообщением "Вход". (см. мой ответ ниже).

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

4b9b3361

Ответ 1

Лучший способ добиться этого - иметь сервер авторизации (webAPI, генерирующий токен) и среднюю рекламу потребления токенов в вашем проекте MVC. Идентификационный сервер https://github.com/IdentityServer/IdentityServer3 должен помочь. Однако я сделал это как ниже

Построен сервер авторизации с использованием JWT с API-интерфейсом WEB и идентификатором ASP.Net, как описано здесь http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/

после того, как вы сделаете так, чтобы ваш startup.cc вашего веб-сайта выглядел ниже

//Настраивает файл cookie для веб-приложений и JWT для SPA, мобильных приложений

 private void ConfigureOAuthTokenGeneration(IAppBuilder app)
 {
    // Configure the db context, user manager and role manager to use a single instance per request
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

    //Cookie for old school MVC application
    var cookieOptions = new CookieAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        CookieHttpOnly = true, // JavaScript should use the Bearer
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,                
        LoginPath = new PathString("/api/Account/Login"),
        CookieName = "AuthCookie"
    };
    // Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    OAuthServerOptions = new OAuthAuthorizationServerOptions()
    {
        //For Dev enviroment only (on production should be AllowInsecureHttp = false)
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/oauth/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromDays(30),
        Provider = new CustomOAuthProvider(),                
        AccessTokenFormat = new CustomJwtFormat(ConfigurationManager.AppSettings["JWTPath"])
    };

    // OAuth 2.0 Bearer Access Token Generation
    app.UseOAuthAuthorizationServer(OAuthServerOptions);

}

Здесь вы можете найти классы CustomOAuthProvider, CustomJwtFormat https://github.com/tjoudeh/AspNetIdentity.WebApi/tree/master/AspNetIdentity.WebApi/Providers

Напишите логику потребления (т.е. промежуточное ПО) во всех моих других API (серверах ресурсов), которые вы хотите защитить, используя тот же токен. Поскольку вы хотите использовать токен, сгенерированный webAPI в вашем проекте MVC, после внедрения сервера авторизации вам нужно сделать ниже

В приложении MVC добавьте ниже в startup.cs

public void Configuration(IAppBuilder app)
{
        ConfigureOAuthTokenConsumption(app);
}

private void ConfigureOAuthTokenConsumption(IAppBuilder app)
{
    var issuer = ConfigurationManager.AppSettings["AuthIssuer"];
    string audienceid = ConfigurationManager.AppSettings["AudienceId"];
    byte[] audiencesecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);

    app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieName = "AuthCookie" , AuthenticationType=DefaultAuthenticationTypes.ApplicationCookie });

    //// Api controllers with an [Authorize] attribute will be validated with JWT
    app.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Passive,
            AuthenticationType = "JWT",
            AllowedAudiences = new[] { audienceid },
            IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
            {
                new SymmetricKeyIssuerSecurityTokenProvider(issuer, audiencesecret)                           
            }

        });
}

В вашем MVC-контроллере, когда вы получаете де-сериализацию этого токена и генерируете cookie из токена доступа

    AccessClaims claimsToken = new AccessClaims();
    claimsToken = JsonConvert.DeserializeObject<AccessClaims>(response.Content);
    claimsToken.Cookie = response.Cookies[0].Value;               
    Request.Headers.Add("Authorization", "bearer " + claimsToken.access_token);
    var ctx = Request.GetOwinContext();
    var authenticateResult = await ctx.Authentication.AuthenticateAsync("JWT");
    ctx.Authentication.SignOut("JWT");
    var applicationCookieIdentity = new ClaimsIdentity(authenticateResult.Identity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
    ctx.Authentication.SignIn(applicationCookieIdentity);

Создайте машинный ключ и добавьте его в web.config вашего сайта webAPI и ASP.Net MVC.

С этим будет создан файл cookie и атрибут [Authorize] в MVC Site и WebAPI будут отмечать этот файл cookie.

P.S. - Я сделал это с помощью веб-API, выдающего JWT (сервер авторизации или сервера Auth и ресурсов) и успешно использующийся на веб-сайте ASP.Net MVC, сайт SPA, построенный в Angular, защищенные API, встроенные в python (сервер ресурсов), spring (сервер ресурсов), приложение для Android.

Ответ 2

Ugg... мне нужно было использовать форму Login.cshtml и переопределить отправку... сделать вызов Ajax, чтобы получить токен на предъявителя WebApi... и затем отправить форму для получения фактического MVC печенье. Итак, я фактически делаю два регистрационных запроса... один для токена WebApi, а другой для файла cookie MVC.

Казалось бы, довольно хреново для меня... было бы неплохо, если бы был какой-то способ входа в MVC с использованием токена-носителя... или вызов WebApi, который вернет мне куки файлы, которые я могу использовать для обычных Запросы страницы MVC.

Если у кого-то есть лучший способ, я бы с удовольствием его услышал.

Это script код, который я добавил в Login.cshtml:

    $(document).ready(function () {
        $('form:first').submit(function (e) {
            e.preventDefault();
            var $form = $(this);
            var formData = $form.serializeObject(); // https://github.com/macek/jquery-serialize-object
            formData.grant_type = "password";
            $.ajax({
                type: "POST",
                url: '@Url.Content("~/Token")',
                dataType: "json",
                data: formData, // seems like the data must be in json format
                success: function (data) {
                    sessionStorage.setItem('token', data.access_token);
                    $form.get(0).submit(); // do the actual page post now
                },
                error: function (textStatus, errorThrown) {
                }
            });
        });
    });

Ответ 3

У меня есть похожий случай с вами, но я использую другой способ аутентификации.

У меня есть сеть и api, которые все для пользователей интрасети. Я не использую идентификатор пользователя для передачи web и api. Вместо этого я создал отдельную учетную запись в Интернете, и каждый раз, когда сеть будет использовать эту специальную учетную запись для подключения к api.

Поскольку нам также необходимо убедиться, что пользователи не должны напрямую подключаться к api. Они должны подключаться только к web ui.

Надеюсь, это поможет вам.

Ответ 4

Я предполагаю, что вы пытаетесь сделать страницы, обслуживаемые MVC, javascript, который вызывает вызовы методов Web API. Если вы используете идентификатор ASP.NET для проверки подлинности (как это выглядит, как вы это делаете), тогда MVC должен использовать токены OAuth, которые могут быть переданы в веб-API для аутентификации.

Вот фрагмент из кода javascript, который работает для меня в аналогичной ситуации:

var token = sessionStorage.getItem('access_token');
var headers = {};
if (token) {
    headers.Authorization = 'Bearer ' + token;
}
$.ajax({
    type: <GET/POSt/...>,
    url: <your api>,
    headers: headers
}).done(function (result, textStatus) {

Ответ 5

Вот решение вашей проблемы. Вы можете использовать Auth0 здесь ссылка

  • Пользователь вводит свои учетные данные   Сервер проверяет правильность учетных данных и возвращает подписанный токен

  • Этот токен хранится на стороне клиента, чаще всего в локальном хранилище - но могут также храниться в хранилище сеансов или в файле cookie.

  • Последующие запросы на сервер включают этот токен в качестве дополнительный заголовок авторизации или один из других методов упомянутый выше

  • Сервер декодирует JWT, и если токен действителен, запрос

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

Ответ 6

Из ваших комментариев выше, из того, что я понимаю, у вас есть сценарий, в котором вы выполняете вход через браузер, но также должны вызывать методы web-api с помощью вызовов ajax.

Вызовы браузера основаны на сеансах. В то время как вызовы ajax из браузера будут иметь cookie сеанса в заголовке, требуется, чтобы заголовок аутентификации присутствовал для веб-api для выполнения проверки.

Таким образом, при успешном входе в систему вам также необходимо создать токен, основанный на веб-api, установить его как файл cookie (который доступен javascript), а затем при создании ajax-звонков, забрать его из файла cookie и включить его как заголовок в заголовке "Авторизация".