获取访问令牌以从我的 ASP.NET Core 5 MVC 网络应用程序调用 API
Getting access token to call an API from my ASP.NET Core 5 MVC web app
我正在努力思考如何在我的 ASP.NET Core 5 应用程序中使用 Azure Active Directory 和 OpenID Connect 正确验证用户身份,并获得必要的访问令牌以便我可以发出 REST 请求到 API.
我在 Azure AD 中有两个应用程序注册:
- MyAPI - 公开两个“范围”(在“公开 API”中)- 一个给普通用户,一个给管理员
- MyApp - 使用 MyAPI 作为“API 权限”
在我的 ASP.NET Core 5 MVC 应用程序中,我在启动时设置了 OpenID Connect:
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration["AzureAdConfig:Authority"];
options.RequireHttpsMetadata = true;
options.ClientId = Configuration["AzureAdConfig:ClientId"];
options.ClientSecret = Configuration["AzureAdConfig:ClientSecret"];
// options.GetClaimsFromUserInfoEndpoint = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.UsePkce = true;
options.Scope.Add("offline_access");
options.Scope.Add("profile");
options.Scope.Add("api://e968735b-d85e-4359-b364-a9637e4a920d/myapi.data.api");
options.SaveTokens = true;
});
这似乎有效 - 我绝对可以在家庭控制器的 Index
方法中访问我的经过身份验证的用户,并且我看到了所有常见的预期用户声明 - 但我没有看到任何访问令牌可以调用“我的API”。
在我的 MVC 应用程序中,我有一个 class 来访问 API,它使用 HttpClient
- 像这样:
HttpClient _httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(baseUrl);
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
// but where and how can I get this access token I need to call "MyApi" ?
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
我似乎无法弄清楚如何从原始的 OpenID Connect 调用或其他方式获取访问令牌,以便将 Bearer (token)
身份验证令牌提供给 HttpClient
打那些电话。
有什么想法吗?我已经研究了很多博客 post,而且很多都有过时的信息,这使得很难找到正确的、最新的和有效的指导....
更新
我尝试了 Tore 的回答,但首先我得到一个错误:
Exception: Correlation failed.
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
这似乎是因为我没有在我的 OIDC 选项中指定 CallbackPath
。
现在我这样做了:
options.CallbackPath = "/localhost:51233/signin-oidc";
即使 完全 匹配我的 Azure 应用程序注册中定义的“重定向 URL”之一:
现在我收到 这个 错误:
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: '
也尝试过 https://localhost:51233...
但这没有任何区别。
还有其他想法吗?
要调用 API,您可以使用:
var accessToken = await HttpContext.GetTokenAsync("access_token");
var authheader = new AuthenticationHeaderValue("Bearer", accessToken);
var client = new HttpClient();
var authheader = new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Authorization = authheader;
var content = await client.GetStringAsync("https://localhost:7001/api/payment");
ViewBag.Json = JObject.Parse(content).ToString();
return View();
使用options.SaveTokens = true; (在 AddOpenIDConnect 中)会将所有令牌保存在用户 cookie 中,然后您可以使用以下方式访问它:
var accessToken = await HttpContext.GetTokenAsync("access_token");
Sample code to get all the tokens if provided:
ViewBag.access_token = HttpContext.GetTokenAsync("access_token").Result;
ViewBag.id_token = HttpContext.GetTokenAsync("id_token").Result;
ViewBag.refresh_token = HttpContext.GetTokenAsync("refresh_token").Result;
ViewBag.token_type = HttpContext.GetTokenAsync("token_type").Result; //Bearer
ViewBag.expires_at = HttpContext.GetTokenAsync("expires_at").Result; // "2021-02-01T10:58:28.0000000+00:00"
您使用的是 HTTPS 吗?那么您可能会遇到问题,因为如果 HTTPS 在您的应用程序外部终止,则您在 public 互联网上使用 运行 HTTPS,但在内部您使用 HTTP。我通常将我的应用程序托管为 Azure 容器实例,因为这样我就可以将 HTTPS 流量直接发送到我的 container/application.
我想我知道答案了,而且很简单!这个错误我犯过太多次了,所以我完全理解。
注意你写的,绿色墨水包围的端口是51233,但后来你有51223,最后一个显然是行不通的,因为不匹配。
此外,它说 'implicit grant settings enabled',这实际上是另一个错误。在这种情况下,您必须考虑在客户端
中设置另一个不同的流程,如 https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow 所示
我正在努力思考如何在我的 ASP.NET Core 5 应用程序中使用 Azure Active Directory 和 OpenID Connect 正确验证用户身份,并获得必要的访问令牌以便我可以发出 REST 请求到 API.
我在 Azure AD 中有两个应用程序注册:
- MyAPI - 公开两个“范围”(在“公开 API”中)- 一个给普通用户,一个给管理员
- MyApp - 使用 MyAPI 作为“API 权限”
在我的 ASP.NET Core 5 MVC 应用程序中,我在启动时设置了 OpenID Connect:
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration["AzureAdConfig:Authority"];
options.RequireHttpsMetadata = true;
options.ClientId = Configuration["AzureAdConfig:ClientId"];
options.ClientSecret = Configuration["AzureAdConfig:ClientSecret"];
// options.GetClaimsFromUserInfoEndpoint = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.UsePkce = true;
options.Scope.Add("offline_access");
options.Scope.Add("profile");
options.Scope.Add("api://e968735b-d85e-4359-b364-a9637e4a920d/myapi.data.api");
options.SaveTokens = true;
});
这似乎有效 - 我绝对可以在家庭控制器的 Index
方法中访问我的经过身份验证的用户,并且我看到了所有常见的预期用户声明 - 但我没有看到任何访问令牌可以调用“我的API”。
在我的 MVC 应用程序中,我有一个 class 来访问 API,它使用 HttpClient
- 像这样:
HttpClient _httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(baseUrl);
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
// but where and how can I get this access token I need to call "MyApi" ?
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
我似乎无法弄清楚如何从原始的 OpenID Connect 调用或其他方式获取访问令牌,以便将 Bearer (token)
身份验证令牌提供给 HttpClient
打那些电话。
有什么想法吗?我已经研究了很多博客 post,而且很多都有过时的信息,这使得很难找到正确的、最新的和有效的指导....
更新
我尝试了 Tore 的回答,但首先我得到一个错误:
Exception: Correlation failed.
Unknown locationException: An error was encountered while handling the remote login. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
这似乎是因为我没有在我的 OIDC 选项中指定 CallbackPath
。
现在我这样做了:
options.CallbackPath = "/localhost:51233/signin-oidc";
即使 完全 匹配我的 Azure 应用程序注册中定义的“重定向 URL”之一:
现在我收到 这个 错误:
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: '
也尝试过 https://localhost:51233...
但这没有任何区别。
还有其他想法吗?
要调用 API,您可以使用:
var accessToken = await HttpContext.GetTokenAsync("access_token");
var authheader = new AuthenticationHeaderValue("Bearer", accessToken);
var client = new HttpClient();
var authheader = new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Authorization = authheader;
var content = await client.GetStringAsync("https://localhost:7001/api/payment");
ViewBag.Json = JObject.Parse(content).ToString();
return View();
使用options.SaveTokens = true; (在 AddOpenIDConnect 中)会将所有令牌保存在用户 cookie 中,然后您可以使用以下方式访问它:
var accessToken = await HttpContext.GetTokenAsync("access_token");
Sample code to get all the tokens if provided:
ViewBag.access_token = HttpContext.GetTokenAsync("access_token").Result;
ViewBag.id_token = HttpContext.GetTokenAsync("id_token").Result;
ViewBag.refresh_token = HttpContext.GetTokenAsync("refresh_token").Result;
ViewBag.token_type = HttpContext.GetTokenAsync("token_type").Result; //Bearer
ViewBag.expires_at = HttpContext.GetTokenAsync("expires_at").Result; // "2021-02-01T10:58:28.0000000+00:00"
您使用的是 HTTPS 吗?那么您可能会遇到问题,因为如果 HTTPS 在您的应用程序外部终止,则您在 public 互联网上使用 运行 HTTPS,但在内部您使用 HTTP。我通常将我的应用程序托管为 Azure 容器实例,因为这样我就可以将 HTTPS 流量直接发送到我的 container/application.
我想我知道答案了,而且很简单!这个错误我犯过太多次了,所以我完全理解。
注意你写的,绿色墨水包围的端口是51233,但后来你有51223,最后一个显然是行不通的,因为不匹配。
此外,它说 'implicit grant settings enabled',这实际上是另一个错误。在这种情况下,您必须考虑在客户端
中设置另一个不同的流程,如 https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow 所示