从Web API将承载令牌存储在MVC中的位置 [英] Where to store Bearer Token in MVC from Web API

查看:82
本文介绍了从Web API将承载令牌存储在MVC中的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景

我有一个ASP.NET Web API,该API使用OAuth密码流提供承载令牌来访问其资源.

I have an ASP.NET Web API that uses the OAuth Password Flow to provide Bearer Tokens to gain access to its resources.

我现在正在制作需要使用此API的MVC应用.

I'm now in the process of making an MVC app that will need to use this API.

计划是让MVC控制器代表客户端浏览器对API进行调用.

The plan is to have the MVC controllers make calls to the API on behalf of the client browser.

来自浏览器的ajax请求将命中MVC控制器,然后进行API调用.然后将结果作为JSON反馈给客户端,并使用Java脚本进行处理.

The ajax requests from the browser will hit the MVC controllers and then the API calls are made. Results are then fed back to the client as JSON and handles in java-script.

客户端永远不应直接与API通信.

The client should never communicate directly with the API.

获得身份验证.

一旦成功通过调用Web api令牌端点在MVC应用程序中收到了Bearer令牌,我就需要找到最佳的处理方式.

I need to find the best way to handle the Bearer Token once it has been received in the MVC app via a successful call to the web api token endpoint.

在以后对api的任何调用中,我都需要使用此承载令牌.

I need to use this bearer token in any subsequent calls to the api.

我的计划是将其存储在System.Web.HttpContext.Current.Session["BearerToken"]

My plan is to store it in the System.Web.HttpContext.Current.Session["BearerToken"]

然后我可以创建一个自定义的AuthorizationAttribute,它将检查当前HttpContext中是否存在BearerToken,如果不存在,则客户端将需要重新访问令牌端点.

I can then create a custom AuthorizationAttribute that will check to see if a BearerToken is present in the current HttpContext, if it is not present, the client will need to revisit the token endpoint.

这似乎可行吗?

我要征求人们的意见,因为我不相信这是我项目的最佳解决方案.

I'm asking for peoples opinion on this as I am not convinced this the best solution for my project.

推荐答案

我设法提出了一些我认为效果很好的方法.

I've managed to come up with something that i think will work quite well.

我正在使用Owin中间件进行Cookie身份验证.

I'm using the Owin Middleware for Cookie Authentication.

在MVC应用程序中,我有一个Owin启动文件,其中配置了Cookie身份验证:-

Within the MVC Application i have an Owin Startup file where the Cookie Authentication is configured :-

 public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888

            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/Account/Login"),

            });
        }
    }

然后,我使用两个用于登录和注销的Action方法制作了一个AccountController:-

I then made an AccountController with two Action methods for Logging In and Logging out :-

登录.

public ActionResult Login(LoginModel model,string returnUrl)
        {
            var getTokenUrl = string.Format(ApiEndPoints.AuthorisationTokenEndpoint.Post.Token, ConfigurationManager.AppSettings["ApiBaseUri"]);

            using (HttpClient httpClient = new HttpClient())
            {
                HttpContent content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("grant_type", "password"), 
                    new KeyValuePair<string, string>("username", model.EmailAddress), 
                    new KeyValuePair<string, string>("password", model.Password)
                });

                HttpResponseMessage result = httpClient.PostAsync(getTokenUrl, content).Result;

                string resultContent = result.Content.ReadAsStringAsync().Result;

                var token = JsonConvert.DeserializeObject<Token>(resultContent);

                AuthenticationProperties options = new AuthenticationProperties();

                options.AllowRefresh = true;
                options.IsPersistent = true;
                options.ExpiresUtc = DateTime.UtcNow.AddSeconds(int.Parse(token.expires_in));

                var claims = new[]
                {
                    new Claim(ClaimTypes.Name, model.EmailAddress),
                    new Claim("AcessToken", string.Format("Bearer {0}", token.access_token)),
                };

                var identity = new ClaimsIdentity(claims, "ApplicationCookie");

                Request.GetOwinContext().Authentication.SignIn(options, identity);

            }

            return RedirectToAction("Index", "Home");
        }

注销

  public ActionResult LogOut()
            {
                Request.GetOwinContext().Authentication.SignOut("ApplicationCookie");

                return RedirectToAction("Login");
            }

保护资源

    [Authorize]
    public class HomeController : Controller
    {

        private readonly IUserSession _userSession;

        public HomeController(IUserSession userSession)
        {
            _userSession = userSession;
        }

        // GET: Home
        public ActionResult Index()
        {

            ViewBag.EmailAddress = _userSession.Username;
            ViewBag.AccessToken = _userSession.BearerToken;

            return View();
        }
    }


 public interface IUserSession
    {
        string Username { get; }
        string BearerToken { get; }
    }

public class UserSession : IUserSession
    {

        public string Username
        {
            get { return ((ClaimsPrincipal)HttpContext.Current.User).FindFirst(ClaimTypes.Name).Value; }
        }

        public string BearerToken
        {
            get { return ((ClaimsPrincipal)HttpContext.Current.User).FindFirst("AcessToken").Value; }
        }

    }

这篇关于从Web API将承载令牌存储在MVC中的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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