我计划使用ASP。NET Identity 2.0在ASP。NET MVC应用程序进行身份验证和授权。
参考以下链接
ASP。NET Web API 2使用Owin
我能够为有效用户创建访问令牌(JWT),即,当用户登录到应用程序时,我将使用名称和密码验证用户,然后我将为该有效用户发布JSON web令牌。
现在,我在一些文章中读到,我们需要在每个请求的头中传递承载令牌,以验证用户的身份验证。在MVC中,我们将为需要保护的方法提供Authorize属性,如下所示…
public class UserController : BaseHRAppController
{
[Authorize]
public ActionResult Index()
{
return View();
}
}
如何告诉我的MVC应用程序使用JWT来验证用户?
每当用户试图访问具有authorize属性的方法时,我想让我的MVC应用程序使用JWT来验证用户。由于我将在许多页面中使用AJAX调用来访问MVC控制器中的方法,所以我认为在每个AJAX请求上传递一个令牌是不好的。我需要帮助以一种有效的方式使用ASP来完成身份验证和授权。NET Identity。
目前,我不知道如何在MVC应用程序中使用这个JWT令牌进行身份验证和授权。
为了让MVC了解关于JWT的任何东西,你基本上必须告诉它:-)。首先,从nuget:安装Jwt包
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)
}
});
}
}
}
您会注意到,我正在将颁发者、audienceId和audienceSecret放在Web.config文件中。(这些值应该与资源服务器上的值相匹配)。此外,您可能需要确保您有一个更新的系统。IdentityModel。代币。Jwt运行:
Update-package System.IdentityModel.Tokens.Jwt
有了这些设置,您可以用[Authorize]属性装饰控制器Action并打球。
打球当然意味着从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);
UPDATE顺便说一句,如果您希望在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>
当然,用你自己的替换"值">
我不知道你是否解决了这个问题,但我遇到了类似的问题,决定使用FormsAuthentication存储令牌,我可以对令牌进行加密,在每次请求时,cookie都会被传递回来,然后我可以解密它以获得JWT,然后从中提取角色/声明,然后使用这些角色来创建和标识主体,这将允许我用[Authorize(Role="blah,blah")]装饰我的控制器方法。
下面是一些示例代码。
一旦您在登录后从api获得JSON web令牌,您就可以使用以下内容:
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访问令牌以及过期日期存储在FormsAuthentication cookie中。
然后,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访问令牌,然后可以使用系统对其进行解码。IdentityModel。代币。来自Microsoft的Jwt库,然后获取这些角色和ID,并生成用户的主体和标识,从而创建具有这些角色的用户。
然后可以根据[授权]属性验证这些角色。