![](/img/trans.png)
[英]How do I implement an OAuth2 Authorization_Code Flow in Web Api using OWIN Middleware?
[英]How to obtain an Oauth2 bearer token in C# using authorization_code?
我有一個郵遞員請求,它在獲取不記名令牌時可以正常工作,我可以抓取並使用它來發出成功的請求。 但是我無法在 c# 中獲得同樣有效的不記名令牌,並且我嘗試了大約 100 種不同的方法。
這是 Postman 請求,它獲取有效的不記名令牌:
范圍: AX.FullAccess CustomService.FullAccess Odata.FullAccess
認證網址: https://login.microsoftonline.com/abe3ad26.../oauth2/authorize?resource=https://myCust.sandbox.operations.dynamics.com/
://login.microsoftonline.com/abe3ad26.../oauth2/authorize?resource=https://myCust.sandbox.operations.dynamics.com/
在Client Authentication
下拉菜單中有 2 個選項。 另一個選項是Send as basic auth header
。 我選擇哪個並不重要,它們都有效。
這是我的非工作 c# 試圖做郵遞員所做的同樣的事情:
using(WebClient client = new WebClient()) {
var querystring = new System.Collections.Specialized.NameValueCollection();
querystring.Add("grant_type", "authorization_code");
querystring.Add("client_id", "e93c4014...");
querystring.Add("client_secret", "USu8Q...");
querystring.Add("redirect_uri", "https://myCust.sandbox.operations.dynamics.com/");
querystring.Add("resource", "https://myCust.sandbox.operations.dynamics.com/");
querystring.Add("scope", "AX.FullAccess CustomService.FullAccess Odata.FullAccess");
byte[] responsebytes = client.UploadValues("https://login.microsoftonline.com/abe3ad26.../oauth2/authorize", "POST", querystring);
[code to retrieve the response...]
}
在我嘗試過的上述代碼的所有各種排列中,我要么得到一個沒有消息的異常,要么得到一個大的 html 響應,它只是 Microsoft 的通用頁面,標題為Sign in to your account
。
我不確定resource
是否應該是正式的參數,或者像郵遞員一樣附加到Auth URL
,或者什么。
我確定client_id
和client_secret
在name
和value
上都是正確的。 至於所有其他參數,我不確定。 我特別不確定我應該將此請求發布到哪個確切的網址。 我已經嘗試了帶有和不帶有資源查詢字符串值的完整Auth URL
,無論哪種方式都沒有運氣。
一個問題是您應該始終要求openid范圍。
這是大多數身份提供者的必需范圍。
下面是我用來從 openid-connect 令牌提供程序獲取令牌的 C# 代碼:(使用 Flurl.Http NuGet 包)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
using Microsoft.AspNetCore.Mvc;
using OpenID_Connect_client.Models;
public class CodeFlowController : Controller
{
private readonly IOpenIDSettings _openIdSettings;
public CodeFlowController(IOpenIDSettings openIdSettings)
{
this._openIdSettings = openIdSettings;
}
/// <summary>
/// Start page for the login using the fragment as return type
/// </summary>
/// <returns></returns>
public IActionResult Login()
{
string url = BuildLoginUrl();
ViewData["loginurl"] = url;
return View();
}
/// <summary>
/// Construct the login URL
/// </summary>
/// <returns></returns>
private string BuildLoginUrl()
{
//In real life, nonce and state should be random values, but we hardcoded them here for simplicity
string nonceValue = "1122334455";
string stateValue = "9988776655";
//Please redirect us back to this page after successful login
string redirectUrl = "https://localhost:5001/CodeFlow/callback";
var url = new Url(_openIdSettings.authorization_endpoint);
url = url.SetQueryParams(new
{
response_type = "code", //Get both access-token + ID-token
client_id = "authcodeflowclient", //Id of this client
scope = "openid email profile shop.admin", //openid (required; to indicate that the application intends to use OIDC to verify the user's identity)
prompt = "consent", // Force users to provide consent
response_mode = "form_post", // Send the token response as a form post instead of a fragment encoded redirect
state = stateValue, // To prevent CSRF attacks
nonce = nonceValue, // To further strengthen the security
redirect_uri = redirectUrl // The URL to which the Auth0 will redirect the user's browser after authorization has been granted by the user.
});
return url.ToString();
}
/// <summary>
/// This method is called with the authorization code and state parameter
/// </summary>
/// <param name="code">authorization code generated by the authorization server. This code is relatively short-lived, typically lasting between 1 to 10 minutes depending on the OAuth service.</param>
/// <param name="state"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Callback(string code, string state)
{
//To be secure then the state parameter should be compared to the state sent in the previous step
var url = new Url(_openIdSettings.token_endpoint);
var token = url.PostUrlEncodedAsync(new
{
client_id = "authcodeflowclient", //Id of this client
client_secret = "mysecret",
grant_type = "authorization_code",
code = code,
redirect_uri = "https://localhost:5001/CodeFlow/Callback"
}).ReceiveJson<Token>().Result;
return View(token);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.