![](/img/trans.png)
[英]How to migrate IdentityServer Bearer Token Authentication from asp.net to .net core 3.1
[英]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中間件,即UseOAuthAuthorizationServer
和UseJwtBearerAuthentication
,它們來自一些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();
}
}
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.