C# 如何从asp.net获取承载令牌作为http响应

C# 如何从asp.net获取承载令牌作为http响应,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我有一个带有前端和web api部分的asp.net应用程序。我希望移动应用程序能够使用受保护的web api端点。这意味着我需要登录并在本机移动应用程序中处理身份验证令牌 现在,我登录asp.net应用程序的唯一方法是通过默认的asp.net/帐户/登录页面。当我发布到登录端点时,返回的主体只包含应用程序的html。然后通过asp.net将令牌存储在cookies中 由于我正在尝试从我的本地移动应用程序登录,因此我不需要html响应,也不希望必须通过cookies来获取令牌 是否可以创建一个单

我有一个带有前端和web api部分的asp.net应用程序。我希望移动应用程序能够使用受保护的web api端点。这意味着我需要登录并在本机移动应用程序中处理身份验证令牌

现在,我登录asp.net应用程序的唯一方法是通过默认的asp.net/帐户/登录页面。当我发布到登录端点时,返回的主体只包含应用程序的html。然后通过asp.net将令牌存储在cookies中

由于我正在尝试从我的本地移动应用程序登录,因此我不需要html响应,也不希望必须通过cookies来获取令牌

是否可以创建一个单独的登录端点,只返回令牌和/或用户详细信息,而不返回应用程序的html内容?这是个坏主意吗

作为参考,这是我提到的默认asp.net登录处理程序

        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, change to shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
            case SignInStatus.Failure:
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }

<>我会考虑JWT/OWIN的组合。基本上,您需要一种机制,该机制将在成功登录后发出令牌OAuth,然后您需要一个中间件,该中间件将使用任何后续请求的http头中的令牌承载器,并使用标准[Authorize]decorator拒绝访问。下面是关于如何使用JWT Json Web令牌的详细介绍

如果你不熟悉OWIN/Katana本身,官方网站上有很多很好的文章。这将非常有用。您基本上只需要两个OWIN中间件,UseAuthAuthorizationServer和UseJWTBeareAuthentication,这两个中间件来自一些NuGet软件包。只需按照上面的例子


在此仅作补充,您提到将令牌承载存储在本机移动应用程序中,请确保将它们存储在或中的适当位置。

在我的手机应用程序中,我使用https调用服务器端API。我在这里提供了我如何授权用户的示例代码…此代码已被修改,以便不显示我的实际过程。您必须修改它以满足您的需要。但它确实展示了一种只调用web服务的方法

在服务端创建以下属性:

using System.Text;
using System.Security.Cryptography;
using System.Web.Http.Filters;
using System.Web.Http.Controllers;
using System.Net.Http;

  public class RequireHttpsAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext.Request.RequestUri.Scheme !=Uri.UriSchemeHttps)
            {
                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                {
                    ReasonPhrase = "HTTPS Required"
                };
            }
            else
            {

                string UserName; 
                String Password;

                if (actionContext.Request.Headers.Any(p => p.Key == "UserName") &&
            actionContext.Request.Headers.Any(p => p.Key == "UserName"))
                {
                    UserName = actionContext.Request.Headers.Where(p => p.Key ==                                            "UserName").FirstOrDefault().Value.FirstOrDefault();

            Password = actionContext.Request.Headers.Where(p => p.Key ==                                            "UserName").FirstOrDefault().Value.FirstOrDefault();

                //do authentication stuff here..
            If(Authorized())
            {
                 base.OnAuthorization(actionContext);
                             return;
            }
            Else
        {

                actionContext.Response = new HttpResponseMessage                            (System.Net.HttpStatusCode.Forbidden)
                        {
                                ReasonPhrase = "Invalid User or Password"
                        };
            }

                }

                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                {
                    ReasonPhrase = "HTTPS Required"
                };


            }
        }

        return ReasonPhrase;
    }
在您的客户端提出如下请求:

string ResponseText= String.Empty();
using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri("https://YOURAPI/");

                    client.DefaultRequestHeaders.Accept.Clear();
                    //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue                   ("text/json"));
                    client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

                    client.DefaultRequestHeaders.Add("UserName", UserName);
                    client.DefaultRequestHeaders.Add("Password", Password);
                    // New code:
                    HttpResponseMessage response = await client.GetAsync            ("api/YOURAPIENDPOINT").ConfigureAwait(continueOnCapturedContext: false);
                    if (response.IsSuccessStatusCode)
                    {
                        ResponseText = await response.Content.ReadAsStringAsync();
                    }
                }
    [RequireHttps]
    public YOURAPI Get(int id)
    {
       //if you got this far then the user is authorized.
    }
API方法应如下所示:

string ResponseText= String.Empty();
using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri("https://YOURAPI/");

                    client.DefaultRequestHeaders.Accept.Clear();
                    //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue                   ("text/json"));
                    client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

                    client.DefaultRequestHeaders.Add("UserName", UserName);
                    client.DefaultRequestHeaders.Add("Password", Password);
                    // New code:
                    HttpResponseMessage response = await client.GetAsync            ("api/YOURAPIENDPOINT").ConfigureAwait(continueOnCapturedContext: false);
                    if (response.IsSuccessStatusCode)
                    {
                        ResponseText = await response.Content.ReadAsStringAsync();
                    }
                }
    [RequireHttps]
    public YOURAPI Get(int id)
    {
       //if you got this far then the user is authorized.
    }

您的里程可能会有所不同。我还没有测试修改后的代码。但是你应该知道如何实现你想要的。

你能添加你的web api部分吗?@Div我的web api代码都不能处理身份验证。它仅通过[Authorize]属性验证承载令牌