结合使用用于MVC页面和Web API页面的身份验证? [英] Combine the use of authentication both for MVC pages and for Web API pages?

查看:1079
本文介绍了结合使用用于MVC页面和Web API页面的身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MVC 5网络应用程序,可以登录Login.cshtml页面,并获得一个cookie,登录工作正常。但是,我想使用Web API登录,然后(也许)设置一个cookie,以便我登录我的MVC页面...(或登录与MVC登录,然后访问Web API),但是web api返回一个承载令牌而不是一个cookie令牌...所以这不工作。有没有办法结合对我的MVC页面和我的Web API页面使用身份验证?

I have an MVC 5 web application and can login with a Login.cshtml page and get a cookie and the login works fine. But, I would like to do a login with the Web API and then (maybe) set a cookie so that I am logged in for my MVC pages... (or login with the MVC login and then access the Web API) however the web api returns a bearer token and not a cookie token... so this doesn't work. Is there a way to combine the use of authentication both for my MVC pages and for my Web API pages?

UPDATE:

这不是真正的代码问题,更多的是一个概念问题。

This isn't really a code issue, more of a conceptual issue.

正常的MVC网页检查一个名为,默认。 ApplicationCookie来确定请求者身份。此cookie是通过调用ApplicationSignInManager.PasswordSignInAsync生成的。

Normal MVC web pages examine a cookie named, by default, ".AspNet.ApplicationCookie" to determine the requesters identity. This cookie is generated by calling ApplicationSignInManager.PasswordSignInAsync.

另一方面,WebAPI调用检查名为Authorization ...的项目的请求头,并使用该值确定请求者身份。这是从WebAPI调用返回的/ Token。

WebAPI calls, on the other hand, examine the requests headers for an item named Authorization... and uses that value to determine the requesters identity. This is returned from a WebAPI call to "/Token".

这些是非常不同的值。我的网站需要同时使用MVC页面和 WebAPI调用(动态更新这些页面)...两者都需要通过身份验证才能执行其任务。

These are very different values. My website needs to use both MVC pages and WebAPI calls (to dynamically update those pages)... and both need to be authenticated to perform their tasks.

我可以想到的唯一方法是实际验证两次...一次使用WebAPI调用,再次使用登录帖子。 (见我下面的答案)。

The only method I can think of is to actually authenticate twice... once with a WebAPI call and again with the Login post. (see my Answer below).

这似乎很黑的...但我不明白授权码足以知道是否有一个更恰当的方式完成

This seems very hacky... but I don't understand the authorization code enough to know if there is a more proper way of accomplishing this.

推荐答案

实现这一点的最佳方式是拥有授权服务器(一个生成令牌的webAPI)在您的MVC project.IdentityServer https://github.com/IdentityServer/IdentityServer3 应该有所帮助。但是我已经这样做了

The best way to achieve this to have a authorization server (a webAPI generating a token) and token consumption middle ware in your MVC project.IdentityServer https://github.com/IdentityServer/IdentityServer3 should help. However I have done this as below

使用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 /

Built an 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

//为Web应用程序和JWT的SPA配置移动应用程序的cookie验证

// 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);

}



您可以在这里找到CustomOAuthProvider,CustomJwtFormat类 https://github.com/tjoudeh/AspNetIdentity.WebApi/tree/master/AspNetIdentity .WebApi / Providers

在所有我想要使用相同令牌保护的API(资源服务器)中写入消费逻辑(即中间件)。因为你想在你的MVC项目中使用webAPI生成的令牌,在实现授权服务器后,你需要做下面

Write a consumption logic (i.e. middleware) in all my other APIs (Resource servers) that you want to secure using same token. Since you want to consume the token generated by webAPI in your MVC project, after implementing Authorization server you need to do below

在你的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控制器中,当您接收令牌反序列化它并生成来自访问令牌的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);

生成机器密钥并将其添加到webAPI和ASP.Net MVC站点的web.config中。

Generate a machine key and add it in web.config of your webAPI and ASP.Net MVC site.

使用这个cookie将创建一个cookie,并且MVC网站中的[Authorize]属性和WebAPI将遵守此cookie。

With this a cookie will be created and [Authorize] attribute in MVC Site and WebAPI will honor this cookie.

PS - 我做了这个与发布JWT(授权服务器或认证和资源服务器)的Web API,并成功地能够在ASP.Net MVC网站,SPA站点内置在Angular,安全API内置在python(资源服务器) spring(资源服务器),Android应用程序。

P.S. - I have done this with a web API issuing JWT (Authorization server or Auth & resource server) and successfully able to consume in a ASP.Net MVC website, SPA Site built in Angular , secure APIs built in python (resource server) , spring (resource server), Android App.

这篇关于结合使用用于MVC页面和Web API页面的身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆