Как использовать JWT в приложении MVC для аутентификации и авторизации?

Я планировал использовать ASP.NET Identity 2.0 в приложении ASP.NET MVC для аутентификации и авторизации.

Ссылаясь на ссылку ниже

JSON Web Token в ASP.NET Web API 2 с использованием Owin

Мне удалось создать токен доступа (JWT) для действительного пользователя, т.е. Когда пользователь входит в приложение, я проверяю пользователя по имени и паролю, а затем выдаю веб-токен JSON для этого действительного пользователя.

Теперь я прочитал в некоторых статьях, что нам нужно передавать маркер-носитель в заголовках для каждого запроса, чтобы подтвердить пользователя для аутентификации. В MVC мы предоставим атрибут Authorize для методов, которые необходимо защитить, как показано ниже…

      public class UserController : BaseHRAppController
      {
            [Authorize]
            public ActionResult Index()
            {          
               return View();
            }
       }

Как указать моему приложению MVC использовать JWT для проверки пользователя?

Я хочу, чтобы мое приложение MVC проверяло пользователя с помощью JWT всякий раз, когда пользователь пытается получить доступ к методу с атрибутом authorize. Поскольку я буду использовать вызовы AJAX на многих страницах для доступа к методу, присутствующему в контроллере MVC, я не считаю правильным передавать токен при каждом запросе AJAX. Мне нужна помощь для эффективной аутентификации и авторизации с использованием ASP.NET Identity в приложении MVC.

В настоящее время я не знаю, как использовать этот токен JWT для аутентификации и авторизации в приложении MVC.

Ответы

Ответ 1

Чтобы MVC мог что-то понять о вашем JWT, вы должны сказать это :-). Сначала установите пакет Jwt из nuget:

Install-Package Microsoft.Owin.Security.Jwt

Затем откройте файл Startup.cs и добавьте новую функцию, которая сообщит MVC, как использовать JWT. Основы вашего стартапа будут выглядеть примерно так:

using System.Configuration;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using Microsoft.Owin.Security.Jwt;
using Owin;

[assembly: OwinStartupAttribute(typeof(TOMS.Frontend.Startup))]
namespace TOMS.Frontend
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            ConfigureOAuthTokenConsumption(app);
        }

        private void ConfigureOAuthTokenConsumption(IAppBuilder app)
        {
            var issuer = ConfigurationManager.AppSettings["Issuer"];
            var audienceId = ConfigurationManager.AppSettings["AudienceId"];
            var audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]);

            // Api controllers with an [Authorize] attribute will be validated with JWT
            app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { audienceId },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret) 
                }
            });
        }
    }
}

Вы заметите, что я помещаю в мой файл Web.config эмитент, audiidid и audisecret. (Эти значения должны совпадать со значениями на вашем сервере ресурсов). Кроме того, вы можете убедиться, что у вас работает обновленный System.IdentityModel.Tokens.Jwt:

Update-package System.IdentityModel.Tokens.Jwt

С этими настройками вы можете украсить свое действие контроллера атрибутом [Authorize] и играть в мяч.

Конечно, играть в мяч означает, что вы отправите запрос из вашего javascript в действие защищенного контроллера:

//assuming you placed the token in a sessionStorage variable called tokenKey when it came back from your Authorization Server
    var token = sessionStorage.getItem(tokenKey);
    var headers = {};
    if (token) {
        headers.Authorization = 'Bearer ' + token;
    }

    $.ajax({
        type: 'GET',
        url: 'CONTROLLER/ACTION',
        headers: headers
    }).done(function (data) {
        self.result(data);
    }).fail(showError);

ОБНОВЛЕНИЕ Кстати, если вы хотите добавить значения в ваш файл web.config, чтобы получить их, как я делал выше; просто добавьте их под AppSettings:

<configuration>
 <appSettings>
    <add key="Issuer" value="YOUR_ISSUER" />
    <add key="AudienceId" value="YOUR_AUDIENCEID" />
    <add key="AudienceSecret" value="YOUR_AUDIENCESECRET" />
 </appSettings>
</configuration>

... конечно, заменив "ценности" своими собственными

Ответ 2

Я не знаю, решили ли вы это, но у меня возникла похожая проблема, и я решил сохранить токен с помощью FormsAuthentication, который был в состоянии зашифровать токен, и при каждом запросе cookie передавался обратно, а затем я мог расшифровать его получите JWT, а затем извлеките роли/утверждения из, а затем используйте эти роли для создания и Identity Principal, который позволил бы мне декорировать методы моего контроллера с помощью [Authorize (Role = "blah, blah")].

Вот пример кода ниже.

Как только вы получите веб-токен JSON из API после входа в систему, вы можете использовать что-то вроде:

var returnedToken = (TokenResponse)result.ReturnedObject;
var ticket = new FormsAuthenticationTicket(1, model.Email, DateTime.Now, ConvertUnitToDateTime(returnedToken.expires_in), true, returnedToken.access_token);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie)

У меня есть некоторые из моих собственных созданных классов и методов, но это даст вам общее представление о том, что вы сохраняете маркер доступа JWT, а также дату истечения срока действия в своем файле cookie FormsAuthentication.

Затем cookie передается с каждым запросом, и в вашем файле Global.asax у вас может быть метод для проверки подлинности запроса:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        JwtSecurityToken jwTok = TokenHelper.GetJWTokenFromCookie(authCookie); 

        // Create the IIdentity instance
        IIdentity id = new FormsIdentity(authTicket);

        // Create the IPrinciple instance
        IPrincipal principal = new GenericPrincipal(id, TokenHelper.GetRolesFromToken(jwTok).ToArray());

        // Set the context user
        Context.User = principal;
    }
}

Таким образом, вы могли бы расшифровать cookie, чтобы получить токен доступа JWT, который затем можно декодировать с помощью библиотеки System.IdentityModel.Tokens.Jwt от Microsoft, а затем взять эти роли и ID и сгенерировать принципал и идентификатор для пользователя, который создает ваш пользователь с ролями.

Затем эти роли могут быть проверены по атрибуту [Authorize].