也许问题比标题更全面。
有很多关于身份验证、 token 、JWT、Azure AD 等的帖子,但所有这些帖子似乎讲述了一个不同的故事,这使得基本概念,至少对我来说,有点不清楚。我将尝试使用我的案例来解释我的问题。
我已经在 Visual 代码中使用 React 构建了一个前端应用程序,并在 Visual Studio .Net Core 2(Web API)中构建了一个后端应用程序。该应用程序托管在 Azure 中,我们希望使用 Azure AD 进行身份验证。
前端使用 Adal-React ( https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries ) 和 Axios ( https://github.com/axios/axios )。
在教程的帮助下,我在前端和 API(后端)中设置了配置,即使用 Azure 环境中列出的 TenantID 和 ClientID。
虽然我已经设置好它并且它正在工作,但它的工作方式对我来说或多或少不清楚。
我将尝试解释我的应用程序中当前的工作流程,并在下面列出我当前的问题:
1 - 用户导航到前端应用程序,adal 检查用户是否通过身份验证,如果不是,则该人被重定向到我们的 azure 登录环境,这在 adal 配置(前端)中设置如下:
const adalConfig = {
tenant: 'vhsprod.onmicrosoft.com',
clientId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx',
endpoints: {
api: 'https://xxxxx.onmicrosoft.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx (client id)',
},
postLogoutRedirectUri: window.location.origin,
redirectUri: 'http://localhost:3000/user-form',
cacheLocation: 'sessionStorage'
};
export const authContext = new AuthenticationContext(adalConfig);
export const getToken = () => {
return authContext.getCachedToken(authContext.config.clientId);
};
2 - 用户需要登录并被检查用户是否存在于 Azure AD 环境中,如果存在,则用户被重定向回前端,我们得到了自己的 token .
3 - 用户在前端打开一个需要来自后端的数据的表单/页面,正在使用刚刚收到的 token 进行 API 调用。调用是在前端使用 Axios 完成的,还配置了 Axios:
export const axiosCallToMyAPI = axios.create({
baseURL: 'http://localhost:52860/api/',
timeout: 5000,
headers: {'Authorization': 'Bearer ' + initialToken}
});
从 Adal 接收初始 token ,我们刚刚收到的 token :
let initialToken = sessionStorage.getItem('adal.idtoken')
4 - 正在调用 API,在这里我们还设置了使用 Azure AD 的配置 (
appsettings.json
):"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantDomain": "xxxx.onmicrosoft.com",
"TenantId": "xxxx.onmicrosoft.com",
"ClientId": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
}
5 - 在 API 的启动类中,正在验证 token :
services
.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Audience = this.Configuration["AzureAd:ClientId"];
options.Authority = $"{this.Configuration["AzureAd:Instance"]}{this.Configuration["AzureAd:TenantId"]}";
options.Events = new JwtBearerEvents()
{
OnTokenValidated = context =>
{
return Task.CompletedTask;
}
};
});
剩下的问题和我所做的假设(阅读了几篇文章)如下:
OnTokenValidated
但这背后的魔力是什么?是否纯粹检查 appsettings
中配置的租户/客户端 ID?使用正在接收的 token ? implicit flow
(前端 --> 后端)和身份验证 openid connect
?换句话说,在使用 Azure 身份验证时,您是自动执行这些/最佳实践,还是应该继续实现? 任何人都可以确认/解释这些问题吗?
如果故事有点笼统,我深表歉意,但目前我们的试错率太高了,我只是想把事情弄清楚。
最佳答案
With the Azure token, which the frontend receives, a call to the API is being made, how does the API knows this token is 'valid'? I know the startup class of the API uses the event OnTokenValidated but what is the magic behind this? Is it purely checking the configured Tenant / Client ID in the appsettings with the token that is being received??
您在配置身份验证时指定了权限。
当应用程序启动时,身份验证处理程序从这样的 URL 下载 OpenId Connect 元数据:https://login.microsoftonline.com/joonasapps.onmicrosoft.com/.well-known/openid-configuration .
从那里它获取公共(public)签名 key 和有效的发行者 URI。
处理程序根据其获得的签名 key 检查 token 的数字签名是否有效、发行者是否有效、受众是否有效以及 token 是否未过期。
In several posts they use/mention a SecretKey / Signing Key, in my example however I have not implemented the SecretKey, yet it still works. Do I need to implement the secret / signing key in my API (backend)? Is it necessary?
检查上面。
I have also read up on Implicit flow, OpenID connect and some other terms. When using Azure AD authentication like in my example, and doing it this way, am I then automatically doing implicit flow (frontend --> backend) and authentication with openid connect? In other words, when using Azure authentication, are you then automatically doing these / the best practices, or should you still implement it?
隐式流意味着客户端可以直接从授权端点获取访问 token ,而不是从 token 端点请求它。
单页应用程序将它与隐藏的 iframe 一起使用来获取访问 token 并刷新过期 token 。
它确实取决于用户与 Azure AD 保持事件状态的 session 。
如果您有一个更“经典”的后端应用程序,您可能会使用授权代码流而不是隐式流。
The token has certain claims /. scopes defined which are being supplied by Azure (where you can also set these claims like email and roles), however when using AspNet (Identity) you can also add your own claims to the current token / session, for example when I add a roleclaim from aspnetidentity to my token. How do these claims differ from the original claim (still bearer / jwt?) and is this a good practice?
你的应用不能修改 Azure AD token ,句点。
如果您修改它,它的签名将不再有效。
相反,ASP.NET Core Identity 使用 cookie + session 来存储登录用户的声明。
因此,生成的用户 session 将包含来自 token 的声明以及您在用户存储中的声明。
关于azure - 使用 Azure AD 的 API 后端 (.NET Core) 中的身份验证基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50410561/