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:
- Í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ó.
- 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.
- Adjon nevet a kapcsolati beállításnak.
- Válassza ki az Általános Oauth 2 szolgáltatót.
- 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.
- 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
: . - 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ó. - 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; }
}
}