也许这个问题比标题更全面。 有很多关于身份验证,令牌,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环境中,用户需要登录并正在检查,如果是,则用户将被重定向回前端,我们得到了自己的令牌即可。
3 - 用户在前端打开一个表单/页面,需要来自后端的数据,正在使用刚收到的令牌进行API调用。正在使用前端的Axios完成调用,还配置了Axios:
export const axiosCallToMyAPI = axios.create({
baseURL: 'http://localhost:52860/api/',
timeout: 5000,
headers: {'Authorization': 'Bearer ' + initialToken}
});
我们刚刚收到的Adal收到了初始令牌:
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的启动类中,正在验证令牌:
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? implicit flow
(前端 - >后端)并使用openid connect
进行身份验证?换句话说,在使用Azure身份验证时,您是自动执行这些/最佳实践,还是应该实现它? 有人能确认/解释这些问题吗?
如果故事有点笼统,我很抱歉,但目前我们的试错率很高,而我正试图清理一下。
答案 0 :(得分:2)
使用前端接收的Azure令牌,正在调用API,API如何知道此令牌是“有效”?我知道API的启动类使用事件OnTokenValidated但这背后的魔力是什么?它是否纯粹使用正在接收的令牌检查appsettings中配置的租户/客户端ID?
您在配置身份验证时指定了权限。 当应用启动时,身份验证处理程序会从这样的URL下载OpenId Connect元数据:https://login.microsoftonline.com/joonasapps.onmicrosoft.com/.well-known/openid-configuration。
从那里获取公共签名密钥和有效的颁发者URI。
处理程序检查令牌的数字签名是否对其获得的签名密钥有效,发行者是否有效,受众是否有效以及令牌未过期。
在几个帖子中,他们使用/提到了一个SecretKey / Signing Key,但在我的例子中,我还没有实现SecretKey,但它仍然有效。我是否需要在API(后端)中实现密钥/签名密钥?有必要吗?
检查上面。
我还读过Implicit flow,OpenID connect和其他一些术语。在我的示例中使用Azure AD身份验证,并以这种方式执行时,我是否会自动执行隐式流(前端 - >后端)和使用openid connect进行身份验证?换句话说,在使用Azure身份验证时,您是自动执行这些/最佳实践,还是应该实现它?
隐式流意味着客户端可以直接从授权端点获取访问令牌,而不是从令牌端点请求它。 单页应用程序将其与隐藏的iframe一起使用以获取访问令牌并刷新过期令牌。 它确实取决于用户与Azure AD保持活动的会话。 如果你有一个更“经典”的后端应用程序,你可能会使用授权代码流而不是隐式流程。
令牌有某些声明/。定义的范围由Azure提供(您也可以在其中设置电子邮件和角色等声明),但是在使用AspNet(身份)时,您还可以将自己的声明添加到当前令牌/会话,例如,当我添加roleclaim时从aspnetidentity到我的令牌。这些索赔与原始索赔(仍然是持票人/ jwt?)有何不同?这是一个好的做法吗?
您的应用无法修改Azure AD令牌,期间。 如果您修改它,它的签名将不再有效。 相反,ASP.NET Core Identity使用cookie +会话来存储已登录用户的声明。 因此,生成的用户会话将包含来自令牌的声明以及您在用户存储中的声明。