簡體   English   中英

如何使用 authentication_code 在 C# 中獲取 Oauth2 不記名令牌?

[英]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_idclient_secretnamevalue上都是正確的。 至於所有其他參數,我不確定。 我特別不確定我應該將此請求發布到哪個確切的網址。 我已經嘗試了帶有和不帶有資源查詢字符串值的完整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.

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