问题描述
我正在尝试在MVC控制器和Web Api控制器之间使用相同的身份验证. Web api位于同一项目中,只是在/Controllers/API/文件夹中.
I'm trying to use the same authentication between the MVC controllers and the Web Api controllers. The Web api is in the same project, just in an /Controllers/API/ folder.
当我通过MVC登录并创建声明和cookie时,似乎无法弄清楚如何使用OWIN进行身份验证,如下例所示.
I can't seem to figure out how to authenticate using OWIN, when I logged in through MVC and created a claim and a cookie like the example below.
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name,"Admin"),
new Claim(ClaimTypes.Role,"Administrator")
, "ApplicationCookie");
var ctx = Request.GetOwinContext();
var authManager = ctx.Authentication;
authManager.SignIn(identity);
return RedirectToAction("Index", "Home", null);
}
在MVC控制器中一切正常,但是我无法在我的Web API控制器上使用[Authorize(Roles ="Administrator"]属性并使其正常工作.无论如何,它总是让我通过.
Everything works fine in the MVC controllers, but I can't use the [Authorize(Roles="Administrator"] attribute on my web API controller and have it work correctly. It always lets me through regardless.
谢谢
我能够解决此问题的唯一方法是让静态类和属性存储IPrincipal,然后在覆盖Authorize Attribute时查找该属性并检查Role是否在那里.哪一个我不确定这是否是个好主意?
Only way I've been able to combat this is having a static class and property store the IPrincipal and then when Overriding the Authorize Attribute, look for that property and check if the Role is there that way. Which im not sure if that is a good idea or not?
推荐答案
您的身份验证代码写在哪里? MVC控制器还是Web API控制器?我建议将其放在您的Web API控制器中,以便以后可以将其用于任何其他应用程序(SPA或任何其他Web应用程序).您需要构建一个授权服务器/资源服务器模型(对不起,我的英语不是确定如何构成这句话).在您的情况下,Web API既是MAPI站点又是资源服务器.
Where is your authentication code written ? MVC Controller or Web API Controller ? I would recommend to have it in your web API controller that way you can later use it for any other application (SPA or any other web application).You need to build a Authorization server/Resource Server model (sorry for my english wasn't sure how to frame this sentence). In your case Web API being both and MVC site being a resource server.
以下是JWT + Cookie中间件的示例
Below is a sample for JWT + Cookie middleware
使用JWT和WEB API和ASP.Net Identity构建授权服务器,如下所述 http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication- in-asp-net-web-api-and-identity-2/
Build a authorization server using JWT with WEB API and ASP.Net Identity as explained here http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/
一旦您这样做,您的webAPIs startup.cs将如下所示
once you do that your webAPIs startup.cs will look like below
/// Configures cookie auth for web apps and JWT for SPA,Mobile apps
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);
}
在您的MVC应用中,将以下内容添加到startup.cs
In your MVC app add below in 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控制器中,当您收到令牌时,将其反序列化并从acceSs令牌生成cookie
In your MVC controller when you receive the token de-serialize it and generate a cookie from the acceSs token
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);
使用此方法将创建一个cookie,并且MVC站点和WebAPI中的[Authorize]属性将支持该cookie.
With this a cookie will be created and [Authorize] attribute in MVC Site and WebAPI will honor this cookie.
这篇关于MVC和Web Api中的Owin身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!