问题
I have a project in MVC using .NET Framework v4.7 with some WebApi on it. What I need to know is how to use a middleware between then to authorize a JWT for HTTP requests and MVC Action requests.
I've searched everywhere looking for a solution sample, but I couldn't find anything.
If anyone could help, I would be grateful.
Sorry for the English.
回答1:
If I grasped your problem statement, I think OWIN might be an option: you decouple your application from underlying hosting and get an extensible pipeline that you can inject middleware into (pretty much like .net core works out of the box).
Even better - it comes with JWT support out of the box (well, you need to install a few nuget packages - see below). Then you simply enable it on your IAppBuilder
and roll with standard [Authorize]
attributes.
To demo this setup, I've put together a working GitHub repo here to illustrate WebApi middleware.
Apart from Microsoft.AspNet.WebApi.Owin
, Microsoft.Owin.Host.SystemWeb
and Microsoft.Owin.Security.Jwt
nuget packages, it's pretty much a stock standard asp.net WebApi project with the following files changed:
/Startup.cs
using System.Text;
using System.Web.Http;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Jwt;
using Owin;
namespace OWIN.WebApi
{
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config); // bootstrap your existing WebApi config
appBuilder.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true, // I guess you don't even have to sign the token
ValidIssuer = "http://localhost",
ValidAudience = "http://localhost",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("jwt_signing_secret_key"))
}
});
appBuilder.UseWebApi(config); // instruct OWIN to take over
}
}
}
/Controllers/ProtectedValuesController.cs
using System.Collections.Generic;
using System.Web.Http;
namespace OWIN.WebApi.Controllers
{
[Authorize]
public class ProtectedValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
}
/Controllers/ObtainJwtController.cs
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using System.Web.Http;
using Microsoft.IdentityModel.Tokens;
using Claim = System.Security.Claims.Claim;
namespace OWIN.WebApi.Controllers
{
// this class is literally just a test harness to help me generate a valid token for popping into Postman.
public class ObtainJwtController: ApiController
{
private string CraftJwt()
{
string key = "jwt_signing_secret_key"; //Secret key which will be used later during validation
var issuer = "http://localhost";
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var permClaims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("valid", "1"),
new Claim("userid", "1"),
new Claim("name", "test")
};
var token = new JwtSecurityToken(issuer,
issuer,
permClaims,
expires: DateTime.Now.AddDays(1),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
public string Get()
{
return $"Bearer {CraftJwt()}";
}
}
}
This appears to work for MVC too
I have added a few extra nuget packages to do with ASP.NET Identity, which seems to have enabled me to successfully protect the following controller:
/Controllers/Home.cs
using System.Web.Mvc;
namespace OWIN.WebApi.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
[Authorize]
public ActionResult Protected()
{
return View();
}
}
}
Hopefully that gives you some options to explore
回答2:
See what I understand from your question You want to use JWT Token for your WebApi and normal process for your MVC, as for later View generated from server and its not dependent on JWT Token.
I have seen this problem. In one of my application I am hosting both MVC views and webapi, whereas MVC view rely on cookie based authentication and authorization. and WebApi call depend upon JWT token for authorization and authentication.
Sorry this solution is from .net core. you need to configure both Cookie and JWT authentication like this
services.AddCookie()
.AddJwtBearer()
Here default would be your cookie authentication. Now to enable jwt token for your webapi you need to decorate webapi with following attribute
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Hope that's answer your question.
来源:https://stackoverflow.com/questions/52449799/net-framework-mvc-and-web-api-auth-jwt