Megosztás a következőn keresztül:


Identitásszolgáltatók proxyja

Ez a dokumentum bemutatja, hogyan hozhat létre proxyt az OAuth2 protokollt használó egyéni vagy speciális identitásszolgáltatókkal való interakcióhoz.

A Bot Framework lehetővé teszi, hogy a felhasználók az OAuth2 protokollt használó különböző identitásszolgáltatókkal jelentkezzenek be. Az identitásszolgáltatók azonban fejlettebb képességeket vagy alternatív bejelentkezési lehetőségeket kínálva eltérhetnek az alapvető OAuth2 protokolltól. Ezekben az esetekben előfordulhat, hogy nem talál megfelelő kapcsolatbeállítási konfigurációt , amely megfelel Önnek. Lehetséges megoldásként tegye a következőket:

  1. Írjon egy OAuth2-szolgáltatói proxyt , amely a Bot Framework tokenszolgáltatás és a testre szabottabb vagy fejlettebb identitásszolgáltató között található.
  2. Konfigurálja a kapcsolatbeállítást a proxy meghívásához, és kérje meg, hogy a proxy hívja meg az egyéni vagy a speciális identitásszolgáltatót. A proxy a válaszokat is leképezheti vagy átalakíthatja, hogy azok megfeleljenek a Bot Framework tokenszolgáltatás által elvártnak.

OAuth2 proxyszolgáltatás

OAuth2 proxyszolgáltatás létrehozásához két OAuth2 API-val rendelkező REST-szolgáltatást kell implementálnia: egyet az engedélyezéshez, egyet pedig egy jogkivonat lekéréséhez. Az alábbiakban talál egy C#-példát ezekre a módszerekre, valamint arra, hogy mit tehet ezekben a metódusokban egy egyéni vagy speciális identitásszolgáltató meghívásához.

API engedélyezése

Az engedélyezési API egy HTTP GET , amely engedélyezi a hívót, létrehoz egy kódtulajdonságot, és átirányítja az átirányítási URI-ra.

[HttpGet("authorize")]
public ActionResult Authorize(
    string response_type, 
    string client_id, 
    string state, 
    string redirect_uri, 
    string scope = null)
{
    // validate parameters
    if (string.IsNullOrEmpty(state))
    {
        return BadRequest("Authorize request missing parameter 'state'");
    }

    if (string.IsNullOrEmpty(redirect_uri))
    {
        return BadRequest("Authorize request missing parameter 'redirect_uri'");
    }

    // redirect to an external identity provider, 
    // or for this sample, generate a code and token pair and redirect to the redirect_uri

    var code = Guid.NewGuid().ToString("n");
    var token = Guid.NewGuid().ToString("n");
    _tokens.AddOrUpdate(code, token, (c, t) => token);

    return Redirect($"{redirect_uri}?code={code}&state={state}");
}

Token API

A Token API egy HTTP POST , amelyet a Bot Framework tokenszolgáltatás hív meg. A Bot Framework jogkivonat-szolgáltatás elküldi a client_id és client_secret a-t a kérés törzsében. Ezeket az értékeket ellenőrizni kell, és/vagy át kell adni az egyéni vagy speciális identitásszolgáltatónak. A hívásra adott válasz egy JSON-objektum, amely a jogkivonat és a access_token lejárat értékét tartalmazza (az összes többi érték figyelmen kívül lesz hagyva). Ha az identitásszolgáltató egy id_token vagy más értéket ad vissza, amelyet vissza szeretne adni, csak le kell képeznie azt a access_token válasz tulajdonságára, mielőtt visszatér.

[HttpPost("token")]
public async Task<ActionResult> Token()
{
    string body;

    using (var reader = new StreamReader(Request.Body))
    {
        body = await reader.ReadToEndAsync();
    }

    if (string.IsNullOrEmpty(body))
    {
        return BadRequest("Token request missing body");
    }

    var parameters = HttpUtility.ParseQueryString(body);
    string authorizationCode = parameters["code"];
    string grantType = parameters["grant_type"];
    string clientId = parameters["client_id"];
    string clientSecret = parameters["client_secret"];
    string redirectUri= parameters["redirect_uri"];

    // Validate any of these parameters here, or call out to an external identity provider with them

    if (_tokens.TryRemove(authorizationCode, out string token))
    {
        return Ok(new TokenResponse()
        {
            AccessToken = token,
            ExpiresIn = 3600,
            TokenType = "custom",
        });
    }
    else
    {
        return BadRequest("Token request body did not contain parameter 'code'");
    }
}

Proxykapcsolat beállításainak konfigurálása

Miután futtatta az OAuth2 proxyszolgáltatást, létrehozhat egy OAuth-szolgáltatói kapcsolatbeállítást az Azure AI Bot Service-erőforráson. Kövesse az alábbi lépéseket.

  1. Adjon nevet a kapcsolati beállításnak.
  2. Válassza ki az Általános Oauth 2 szolgáltatót.
  3. Adja meg a kapcsolat ügyfél-azonosítóját és titkos ügyfélkulcsát . Ezeket az értékeket a speciális vagy egyéni identitásszolgáltató adja meg, vagy ezek csak a proxyra vonatkozhatnak, ha a használt identitásszolgáltató nem használ ügyfél-azonosítót és titkos kódot.
  4. Az Engedélyezési URL-cím esetében másolja ki az engedélyezési REST API címét, például https://proxy.com/api/oauth/authorize: .
  5. A Token és a Refresh URL-cím esetében másolja ki a jogkivonat REST API-jának címét, például https://proxy.com/api/oauth/token: . A token Exchange URL-címe csak AAD-alapú szolgáltatók esetén érvényes, ezért figyelmen kívül hagyható.
  6. Végül adja hozzá a megfelelő hatóköröket.

OAuthController ASP.NET webalkalmazáshoz

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading.Tasks;
using System.Web;

namespace CustomOAuthProvider.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class OAuthController : ControllerBase
    {
        ConcurrentDictionary<string, string> _tokens;

        public OAuthController(ConcurrentDictionary<string, string> tokens)
        {
            _tokens = tokens;
        }

        [HttpGet("authorize")]
        public ActionResult Authorize(
            string response_type, 
            string client_id, 
            string state, 
            string redirect_uri, 
            string scope = null)
        {
            if (string.IsNullOrEmpty(state))
            {
                return BadRequest("Authorize request missing parameter 'state'");
            }

            if (string.IsNullOrEmpty(redirect_uri))
            {
                return BadRequest("Authorize request missing parameter 'redirect_uri'");
            }

            // reidrect to an external identity provider, 
            // or for this sample, generte a code and token pair and redirect to the redirect_uri

            var code = Guid.NewGuid().ToString("n");
            var token = Guid.NewGuid().ToString("n");
            _tokens.AddOrUpdate(code, token, (c, t) => token);

            return Redirect($"{redirect_uri}?code={code}&state={state}");
        }

        [HttpPost("token")]
        public async Task<ActionResult> Token()
        {
            string body;

            using (var reader = new StreamReader(Request.Body))
            {
                body = await reader.ReadToEndAsync();
            }

            if (string.IsNullOrEmpty(body))
            {
                return BadRequest("Token request missing body");
            }

            var parameters = HttpUtility.ParseQueryString(body);
            string authorizationCode = parameters["code"];
            string grantType = parameters["grant_type"];
            string clientId = parameters["client_id"];
            string clientSecret = parameters["client_secret"];
            string redirectUri= parameters["redirect_uri"];

            // Validate any of these parameters here, or call out to an external identity provider with them

            if (_tokens.TryRemove(authorizationCode, out string token))
            {
                return Ok(new TokenResponse()
                {
                    AccessToken = token,
                    ExpiresIn = 3600,
                    TokenType = "custom",
                });
            }
            else
            {
                return BadRequest("Token request body did not contain parameter 'code'");
            }
        }
    }

    public class TokenResponse
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }

        [JsonProperty("id_token")]
        public string IdToken { get; set; }

        [JsonProperty("token_type")]
        public string TokenType { get; set; }

        [JsonProperty("expires_in")]
        public int ExpiresIn { get; set; }

        [JsonProperty("refresh_token")]
        public string RefreshToken { get; set; }

        [JsonProperty("scope")]
        public string Scope { get; set; }
    }
}