簡體   English   中英

如何從asp.net獲取承載令牌作為http響應

[英]How to get bearer token as http response from asp.net

我有一個帶有前端和Web API部分的asp.net應用程序。 我希望移動應用程序能夠使用受保護的Web API端點。 這意味着我需要登錄並處理本機移動應用程序中的身份驗證令牌。

現在,我可以登錄到asp.net應用程序的唯一方法是通過默認的asp.net / Account / Login頁面。 當我發布到登錄端點時,返回的正文僅包含我的應用程序的html。 然后,令牌由asp.net存儲在cookie中。

由於我正嘗試從本機移動應用程序登錄,因此我不需要html響應,也不需要通過cookie來獲取我的令牌。

是否可以創建一個單獨的登錄端點,該端點僅返回令牌和/或用戶詳細信息,而不返回應用程序的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]裝飾器) 。 這是如何使用JWT(Json Web令牌)的非常好的示例

如果您不熟悉OWIN / Katana本身,則官方網站上有很多不錯的文章。 這將非常有用。 您基本上只需要兩個OWIN中間件,即UseOAuthAuthorizationServerUseJwtBearerAuthentication ,它們來自一些NuGet軟件包。 只需按照上面的示例。

僅在此處完成,您提到將令牌承載存儲在本機移動應用程序中,請確保將它們存儲在AndroidiOS中的適當位置。

在我的電話應用程序中,我使用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();
                    }
                }

API方法應如下所示:

    [RequireHttps]
    public YOURAPI Get(int id)
    {
       //if you got this far then the user is authorized.
    }

你的旅費可能會改變。 我尚未測試此代碼是否已修改。 但是您應該了解如何完成所需的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM