我正在尝试使用Azure Active Directory身份验证创建身份验证,我的应用程序由WebApis和WEb页面组成,如果用户请求应用程序“控制器”页面,我想实现的目标是将用户重定向到Microsoft登录页面,并在通过令牌调用API控制器时授权客户端应用程序。
我设法通过如下设置Startup.Auth.cs来做到这一点
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.IdToken,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
});
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
TokenValidationParameters = new TokenValidationParameters { SaveSigninToken = true, ValidAudience = $"api://{clientId}" }
});
}
用[Authorize]属性装饰我的控制器
但是,当未经授权的客户端应用程序调用API时,它将返回以下内容
<html>
<head>
<title>Working...</title>
</head>
<body>
<form method="POST" name="hiddenform" action="https://local:44341/">
<input type="hidden" name="id_token" value="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiI3NjIzMjcyMC1hNmViLTRkOTctOTI3Yy1lMWFjNzRiODIyMjAiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vYjFmZTVlMmEtZjc1Yy00NDQxLTlmYjItNWFjYzAxYmEwMGQwL3YyLjAiLCJpYXQiOjE2MTA3MzAJub25jZSI6IjYzNzQ2MzI3OTEwNDAxMzk3Ni5aR0k1TmpCaU1XWXRPRGsxT0MwMFpEWmlMV0kxWXprdE9ESTFZMlZrTWpjeU0yWTJNRFZqTWpnNU9EY3RNak0yWkMwME1qWmpMV0UwTTJZdE5XSXpNVFZsTlRKa1pHRXgiLCJvaWQiOiJiN2YzMjg1Mi1hMDRhLTRlOWUtYjFjOS02NTI5NDk3YTgyZDEiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiIyMjQxN0Byai5jb20iLCJyaCI6IjAuQUFBQUtsNy1zVnozUVVWoeHm6x2ad02ExHlw48lfRVZhEoHw8cZ5SWRFOGZfi3TJ3aOFKdaDZZ8Yt1no30Hku8pL3Vf7Lrq-BuKX8PNtkU45aVO1fZf8PFdM4UbpYnHOwvuG1NlPG8mTa1KheQTza9j3PTaiLq8e15jtSoFoHfIJbMZJoNTfvAF40kt9XvYee-rga80Oj1tJX78g_80MmRYORwArr1rq1n6EyPgFHaDDF5vD-zWOLDrXKyj2rwW-7LLpbtojtbsyCPdM5QPkLKnZZFanpvwRAFRTHaLdHINGAlHhvhFP9kvRhVtaTUgwYzrFqlN8k3zSZrvnMOec7A" /><input type="hidden" name="state" value="OpenIdConnect.AuthenticationProperties=7_QsmCbQZ3vBxo1tTvZXcYRLeNQMBZfanq5zpZvqNjuudSAu52-UZnVGkkWMXeBh_rIHE3i_j8g_B751WFqQHR1CXJrdjBi6PZy-" /><input type="hidden" name="session_state" value="5938bc609" /><noscript>
<p>Script is disabled. Click Submit to continue.</p><input type="submit" value="Submit" /></noscript></form>
<script language="javascript">
document.forms[0].submit();
</script>
</body>
</html>
但是,当从我的函数中删除UseOpenIdConnectAuthentication的调用时,它将返回状态码为401的正确响应消息
{ "Message": "Authorization has been denied for this request."}
话虽如此,任何人都可以帮助我如何设置Web api的承载令牌auth和Web应用程序页面的openIdConnect。
谢谢,如果我的方法有误,请告诉我,并根据我的要求推荐正确的方法。
不要在这里使用UseOpenIdConnectAuthentication,它用于自定义OpenID支持,但在这里并不适用,它具有开箱即用的Azure AD特定帮助器,例如您接下来使用的帮助器。
这是服务器端的一个很好的起点:https : //docs.microsoft.com/zh-cn/azure/active-directory/develop/scenario-protected-web-api-overview
对于客户端,通用调用程序(控制台应用程序或任意服务):https : //docs.microsoft.com/zh-cn/azure/active-directory/develop/scenario-daemon-overview
对于客户端,需要保护自己的交互式Web应用程序:https : //docs.microsoft.com/zh-cn/azure/active-directory/develop/scenario-web-app-sign-user-overview
简而言之,您的API客户端必须要求Azure AD提供令牌以访问您的API终结点。为了使Azure AD知道此令牌用于哪个资源,请为您的API创建应用程序注册,然后使用其客户端ID和任何其他必要的参数来配置API应用程序。
当您的应用程序收到令牌时,它将必须与Azure AD联系以对其进行验证。对于此调用,它应使用您在Azure AD中为其生成的客户端ID。
您可能要在模拟真实AD登录时运行客户端,或者您可以以某些AD主体(应用程序注册)运行客户端。看看下面的.NET Core 3.1客户端应用程序示例是否可以助您一臂之力。它使用其ID和机密模拟了一些AD主体,因此它可以在不受管理的身份的情况下从Azure云外部运行并连接到受Azure AD保护的服务。
为了使以下示例正常工作,请确保正确配置客户端应用程序和服务器API的主体(应用程序注册/企业应用程序)。这本身就是一个话题,在上面链接的官方文档中对此进行了很好的描述。
如果您的客户端作为Azure AppService或在Azure VM上运行,则最好使用Azure托管身份。这消除了对秘密的需求,并简化了对AzureServiceTokenProvider的构造函数调用(无参数=使用环境上下文=拾取托管身份)。不幸的是,通过Azure进行本地开发并非那么容易。
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace N
{
public class Test
{
public async Task Main(IConfigurationRoot config, ILoggerFactory loggerFactory)
{
using var httpClient = new HttpClient(new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) =>
{
return true;
}
});
var url = "https://localhost:5000";
var clientId = "guid of your caller's identity App Registration";
var clientSecret = "secret you produced for your caller's managed identity App Registration";
var tenantId = "guid (Azure tenant id)";
var runAs = $"RunAs=App;AppId={clientId};TenantId={tenantId};AppKey={clientSecret}";
var tokenProvider = new AzureServiceTokenProvider(runAs);
var accessToken = await tokenProvider.GetAccessTokenAsync("https://my-test-app-identity.azurewebsites.net");
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(uri));
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
foreach (var header in response.Headers)
{
Console.WriteLine(header.Key + ": " + string.Join(",", header.Value));
}
Console.WriteLine(content);
}
}
}
.csproj中的依赖项:
<PackageReference Include="Azure.Core" Version="1.4.1" />
<PackageReference Include="Azure.Identity" Version="1.2.2" />
<PackageReference Include="Azure.Security.KeyVault.Keys" Version="4.1.0" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.1.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.17.1" />
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句