Как использовать 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].