【问题标题】:How to get a token for downstream service in AAD如何在 AAD 中获取下游服务的令牌
【发布时间】:2015-06-27 11:45:34
【问题描述】:

我有一个 MVC 应用程序,我在其中使用 OpenIdConnectAuthenticationMiddleware 针对 AAD 对用户进行身份验证。此 MVC 应用程序使用一些需要用户身份验证上下文的后端服务。

如果我在 AAD 中单独注册这些服务,我可以使用 AuthenticationContext.AcquireTokenSilentAsync。但是向 AAD 单独注册这些服务似乎是错误的,因为它们需要用户单独同意它们(它们实际上是应用程序的一部分)。

所以我想使用在用户进行身份验证时从 AAD 获得的 JWT 令牌,并将其用作调用下游服务的不记名令牌。我意识到这些服务需要拥有与 MVC 应用程序相同的受众。

但是我如何获得那个 JWT 令牌。 ClaimPrincipal 的第一个身份没有引导上下文。

【问题讨论】:

    标签: c# authentication azure azure-active-directory adal


    【解决方案1】:

    请注意,让您的服务承认具有相同受众的令牌会使您面临令牌转发攻击。我不建议这样做。此外,同意应该发生在一个页面中并且只需单击一次 - 因此就用户影响而言并没有太大区别。 那就是说。如果您确实设置了它,则可以通过将标志 SaveSignInToken 切换为 true 来强制在引导上下文中存在令牌。见

    app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters{SaveSigninToken=true},
                    PostLogoutRedirectUri = postLogoutRedirectUri
                });
    

    【讨论】:

    • 谢谢 Vittorio,我一直在努力解决这个问题。我们有十几个后端服务,但这些与用户或 AAD 管理员无关(实施细节)。用户应该只同意应用程序,而不是它在后端使用的所有服务。推荐的方法是什么?
    • 只要您的应用在其声明中将这些服务列为必需资源,就应该有一个提示。确实,在应用程序旁边看到一长串字符串可能会让某些用户感到困惑,但它应该是一次性的。另一种选择是使用管理员同意 - 在这种情况下,只有管理员会看到提示,然后每个用户都会自动获得同意
    • 啊,所以我可以在清单中列出这些服务并获得一个同意提示!你有关于这方面的更多信息的指针吗?
    • github.com/AzureADSamples/…中查看注册控制器的管理员同意分支
    • 对不起,不代表管理员同意。在哪里可以找到有关将服务列为必需资源的更多信息?还是我错过了什么?
    【解决方案2】:

    编辑 以下是实现此目的的一种方法,但它具有一些安全隐患。您还可以为使用引导上下文设置一个标志。有关更多信息,请参阅 vibronet 的答案。

    OpenIdConnectAuthenticationOptions 中,如果您为SecurityTokenValidatedAuthorizationCodeRecieved 通知配置处理程序,则可以访问通知属性中的id_token。然后,您可以使用该 id_token 作为服务调用中的不记名令牌。您可以通过多种不同的方式使 id_token 在您的控制器中可用。

    一个警告:id_token 将您的网络应用程序的 clientId 作为 aud 声明,而不是应用程序 id uri。因此,在您的服务中,您应该使用 clientId guid 作为您的受众。

    【讨论】:

    • 谢谢,找到令牌。该令牌不应该通过 BootstrapContext 获得吗?从控制器访问该令牌的选项是什么?
    • 同样在通知中,您可以将令牌添加到 ClaimsIdentity 中的声明中。我相信它在 notification.AuthenticationTicket 中。然后你可以通过 ClaimsPrincipal.Current.Claims 在你的控制器中读取它们。不过,这只是一种方式。您还可以使用 http 会话、cookie 或某种形式的后端存储。
    • 这些都是一次性交易。如果您希望令牌始终存在,请参阅其他答案。另外,在多个端点上启用相同的受众之前请三思而后行......令牌转发是真实的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2020-03-08
    相关资源
    最近更新 更多