Use web api cookie for mvc cookie

后端 未结 2 1322
走了就别回头了
走了就别回头了 2020-12-18 09:06

I\'m making a web application by using Web API 2 and MVC 5.

My app has api : api/account/login, which is used for checking posted information and throw status 200 wh

相关标签:
2条回答
  • 2020-12-18 09:22

    You could set the cookie once the user has authenticated against the Account controller.

    public class AccountController 
    {
       public HttpResponseMessage Login() 
       {         
          // Your authentication logic
    
          var responseMessage = new HttpResponseMessage();
    
          var cookie = new CookieHeaderValue("session-id", "12345");
          cookie.Expires = DateTimeOffset.Now.AddDays(1);
          cookie.Domain = Request.RequestUri.Host;
          cookie.Path = "/";
    
          responseMessage.Headers.AddCookies(new CookieHeaderValue[] { cookie });
          return responseMessage;
       }
    }
    

    To authenticate you can put the [Authenticate] attribute on your Home controller.

    public class HomeController
    {
        [Authenticate]
        public ActionResult Index() 
        {
           return View();
        }
    }
    

    The Authenticate attribute can also be applied at the Controller level if needed.

    [Authenticate]
    public class HomeController
    {
    }
    

    You can also make your own authorization attribute if needed by overriding AuthorizeCore and checking for a valid cookie:

    public class CustomAuth : AuthenticationAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            HttpCookie authCookie = httpContext.Request.Cookies["CookieName"];
    
            // Your logic
            return true;
        }
    }
    
    0 讨论(0)
  • 2020-12-18 09:30

    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

    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/

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

    }

    You can find CustomOAuthProvider,CustomJwtFormat classes here https://github.com/tjoudeh/AspNetIdentity.WebApi/tree/master/AspNetIdentity.WebApi/Providers

    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

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

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

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

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

    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.

    0 讨论(0)
提交回复
热议问题