使用Azure AD

时间:2018-05-18 11:40:31

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

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

我留下的问题和我所做的假设(阅读几篇文章)如下:

  • 使用前端收到的Azure令牌,正在调用API,API如何知道此令牌是否有效'?我知道API的启动类使用事件OnTokenValidated,但这个背后的魔力是什么?它是否纯粹使用正在接收的令牌检查appsettings中配置的租户/客户端ID?
  • 在几个帖子中,他们使用/提到了一个SecretKey / Signing Key,但在我的例子中,我还没有实现SecretKey,但它仍然有效。我是否需要在API(后端)中实现密钥/签名密钥?有必要吗?
  • 我还阅读了Implicit flow,OpenID connect和其他一些术语。当像我的示例中那样使用Azure AD身份验证并以这种方式执行时,我是否会自动执行implicit flow(前端 - >后端)并使用openid connect进行身份验证?换句话说,在使用Azure身份验证时,您是自动执行这些/最佳实践,还是应该实现它?
  • 令牌有某些声明/。定义的范围由Azure提供(您也可以在其中设置电子邮件和角色等声明),但是在使用AspNet(身份)时,您还可以将自己的声明添加到当前令牌/会话,例如,当我添加roleclaim时从aspnetidentity到我的令牌。这些索赔与原始索赔(仍然是持票人/ jwt?)有何不同?这是一个好的做法吗?

有人能确认/解释这些问题吗?

如果故事有点笼统,我很抱歉,但目前我们的试错率很高,而我正试图清理一下。

1 个答案:

答案 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 +会话来存储已登录用户的声明。 因此,生成的用户会话将包含来自令牌的声明以及您在用户存储中的声明。