azure - 使用 Azure AD 的 API 后端 (.NET Core) 中的身份验证基础知识

标签 azure authentication asp.net-core jwt azure-active-directory

也许问题比标题更全面。
有很多关于身份验证、 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;
                        }
                    };
                });

剩下的问题和我所做的假设(阅读了几篇文章)如下:
  • 使用前端接收到的 Azure token ,正在调用 API,API 如何知道此 token 是“有效的”?我知道 API 的启动类使用事件 OnTokenValidated但这背后的魔力是什么?是否纯粹检查 appsettings 中配置的租户/客户端 ID?使用正在接收的 token ?
  • 在几篇文章中,他们使用/提到了 SecretKey/签名 key ,但在我的示例中,我还没有实现 SecretKey,但它仍然有效。我是否需要在我的 API(后端)中实现 secret /签名 key ?有必要吗?
  • 我还阅读了隐式流、OpenID 连接和其他一些术语。在我的示例中使用 Azure AD 身份验证并以这种方式进行时,我是否会自动执行 implicit flow (前端 --> 后端)和身份验证 openid connect ?换句话说,在使用 Azure 身份验证时,您是自动执行这些/最佳实践,还是应该继续实现?
  • token 具有某些声明/。由 Azure 提供的范围定义(您还可以在其中设置这些声明,如电子邮件和角色),但是在使用 AspNet(身份)时,您还可以将自己的声明添加到当前 token / session ,例如当我添加角色声明时从 aspnetidentity 到我的 token 。这些声明与原始声明(仍然持有人/jwt?)有何不同,这是一个好的做法吗?

  • 任何人都可以确认/解释这些问题吗?

    如果故事有点笼统,我深表歉意,但目前我们的试错率太高了,我只是想把事情弄清楚。

    最佳答案

    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/

    相关文章:

    Azure 数据工厂 - 将 FTP 递归复制到数据库

    azure - 用于获取指标统计数据的SDK

    facebook - 重新验证功能改变了它的行为?

    ssl - 从 Web App 调用 Web API 时出现证书问题

    asp.net-core - 如何为 ASP.NET Core 注册和使用 MediatR 管道处理程序?

    azure - Applicationhost.config 丢失

    AZURE:通过 az board 工作项上传附件

    authentication - Facebook 是 OpenID 提供商吗?

    oop - 面向对象的登录功能

    asp.net-core - ASP.NET Core修改密码后登录失败