[英]OAuth with custom JWT authentication
我正在努力用OAuth和JWT實現自定義身份驗證流程。 基本上它應該如下:
我一直在關注如何構建OAuth身份驗證的這個很棒的教程 ,唯一不同的部分是Jerrie正在使用Cookies
。
到目前為止我做了什么:
services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = "3rdPartyOAuth";
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie() // Added only because of the DefaultSignInScheme
.AddJwtBearer(options =>
{
options.TokenValidationParameters = // Ommited for brevity
})
.AddOAuth("3rdPartyOAuth", options =>
{
options.ClientId = securityConfig.ClientId;
options.ClientSecret = securityConfig.ClientSecret;
options.CallbackPath = new PathString("/auth/oauthCallback");
options.AuthorizationEndpoint = securityConfig.AuthorizationEndpoint;
options.TokenEndpoint = securityConfig.TokenEndpoint;
options.UserInformationEndpoint = securityConfig.UserInfoEndpoint;
// Only this for testing for now
options.ClaimActions.MapJsonKey("sub", "sub");
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
// Request for user information
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user);
}
};
});
[AllowAnonymous]
[HttpGet("login")]
public IActionResult LoginIam(string returnUrl = "/auth/loginCallback")
{
return Challenge(new AuthenticationProperties() {RedirectUri = returnUrl});
}
[AllowAnonymous]
[DisableRequestSizeLimit]
[HttpGet("loginCallback")]
public IActionResult IamCallback()
{
// Here is where I expect to get the user info, create my JWT and send it back to the client
return Ok();
}
免責聲明:此OAuth流程現已納入。 我有一個創建和使用我自己的JWT工作和一切的流程。 我不會在這里發帖,因為我的問題就在此之前。
在Jerrie的帖子中,您可以看到他設置了DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
。 有了它,當達到/auth/loginCallback
時,我在HttpContext
有用戶聲明。 問題是我的DefaultAuthenticateScheme
設置為JwtBearersDefault
當loginCallback
叫我不能看到用戶無處索賠的Request
。 在這種情況下,如何在回調中訪問OnCreatingTicketEvent
上獲得的信息?
獎金問題:我對OAuth了解不多(現在確定很清楚)。 您可能已經注意到我的options.CallbackPath
與login
端點上的Challenge
中傳遞的RedirectUri
不同。 我希望第三部分OAuth提供程序可以調用option.CallbackPath
,但這不會發生(顯然)。 我必須將CallbackPath
設置為我在OAuth提供程序配置中設置的相同值(如使用GitHub的Jerries教程)才能工作。 是對的嗎? Callback只用於匹配配置嗎? 我甚至可以評論端點CallbackPath
指向它並繼續以相同的方式工作......
謝謝!
改變[AllowAnonymous]
至[Authorize]
在'loginCallback'
端點( AuthController.IamCallback
方法)
驗證
正如Jerrie在帖子中所說的那樣,對auth中間件有一個很好的解釋: https : //digitalmccullough.com/posts/aspnetcore-auth-system-demystified.html
您可以在“ 身份驗證和授權流 ”部分中查看流程圖
第二步是身份驗證中間件調用默認處理程序的身份驗證 。
由於您的默認身份驗證處理程序是Jwt,因此在oauth流之后上下文不會被用戶數據限制,因為它使用CookieAuthenticationDefaults.AuthenticationScheme
嘗試:
[AllowAnonymous]
[DisableRequestSizeLimit]
[HttpGet("loginCallback")]
public IActionResult IamCallback()
{
//
// Read external identity from the temporary cookie
//
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("Nein");
}
var oauthUser = result.Principal;
...
return Ok();
}
偉大的方案摘要: ASP.NET Core 2 AuthenticationSchemes
獎金
我必須將CallbackPath設置為我在OAuth提供程序配置中設置的相同值(如使用GitHub的Jerries教程)才能工作。 是對的嗎?”
是。 出於安全原因,注冊的回調uri(在授權服務器上)和提供的回調uri(由客戶端發送)必須匹配。 因此您無法隨機更改它,或者如果您更改它,您也必須在auth服務器上更改它。
如果沒有此限制,那么帶有mailformed鏈接(帶有修改后的回調網址)的電子郵件可以獲得授權。 這稱為Open Redirect,rfc也引用它: https : //tools.ietf.org/html/rfc6749#section-10.15
OWASP有一個很好的描述: https : //github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md
我甚至可以評論端點CallbackPath指向並繼續以相同的方式工作......“
這是因為您的客戶端是可信任的(您提供了您的秘密,而且您不是一個完全正面的單頁應用程序)。 因此,您可以選擇發送回調uri。 但是如果你發送它,它必須與服務器上注冊的那個匹配。 如果您不發送它,auth服務器將重定向到其側面注冊的URL。
https://tools.ietf.org/html/rfc6749#section-4.1.1
redirect_uri可選。 如3.1.2節所述。
https://tools.ietf.org/html/rfc6749#section-3.1.2
授權服務器在客戶端注冊過程中或在發出授權請求時,將用戶代理重定向到先前使用授權服務器建立的客戶端重定向端點。
https://tools.ietf.org/html/rfc6749#section-3.1.2.2
授權服務器必須要求以下客戶端注冊其重定向端點:
您的客戶是保密的,並使用授權代碼授予類型( https://tools.ietf.org/html/rfc6749#section-1.3.1 )
https://tools.ietf.org/html/rfc6749#section-3.1.2.3
如果已注冊了多個重定向URI,如果只注冊了部分重定向URI,或者沒有注冊重定向URI,則客戶端必須使用“redirect_uri”請求參數包含帶有授權請求的重定向URI。
您已注冊重定向uri,這就是auth服務器不會引發錯誤的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.