使用OWIN Active Directory承载令牌启用多个租户

时间:2015-10-05 02:58:43

标签: active-directory owin adal

我最近开始使用Azure Active Directory来根据我在AngularJS上构建的网站对用户进行身份验证。

使用博客和sample code on GitHub,我已经使用ADAL.js和Katana Bearer Token AD integration的组合使用单租户。

但是,我现在遇到一些支持多个租户的问题。

我有一个页面设置,显示用户ADAL看到它们(通过根范围的userInfo找到),并调用我的服务器,被OWIN接收,并序列化context.Authentication.User

客户端,一切似乎都正常。我可以使用我的任何租户登录,它会为我提供我期望的对象(填充isAuthenticated: trueusername,以及描述用户的profile上的各种属性,登录和租户)。

这是在客户端完成的,方法是将tenant参数留给adalAuthenticationServiceProvider.init调用,如文档中所述。

但是,在服务器端,UseWindowsAzureActiveDirectoryBearerAuthentication方法不喜欢Tenant没有值(因为它会引发异常)。我已经为此尝试了一些值,包括我的应用最初注册的租户,以及我的逻辑最喜欢的“常见”,但无论我放在那里(除非是我试图登录的租户)如果我的ADAL与该租户一起设置,那么它似乎只是跳过这个。

对于它的价值,实际的API调用在[Authorize]过滤器上失败并返回401,这告诉我这不是我的OWIN拦截器的问题。

如何判断UseWindowsAzureActiveDirectoryBearerAuthentication是否支持多租户身份验证?

2 个答案:

答案 0 :(得分:1)

在开发多租户应用程序时,您不能再100%依赖默认的身份验证逻辑。默认的身份验证逻辑假定您声明了要接收令牌的azure AD租户表单,并且将强制执行仅接受租户的令牌表单。这是通过检查与每个租户相关联的元数据文档来完成的,其中包含(除其他事项)租户本身的标识符 - 该标识符必须存在于您收到的令牌中,在iss声明中:任何其他值表示该令牌来自另一个租户,因此必须拒绝。 根据定义,多租户应用程序必须接受来自多个租户的令牌。这是通过使用参数端点(公共端点,请参阅this post)来完成的,该端点允许您“延迟绑定”哪个租户将用于发出令牌。但是,公共端点将提供通用元数据文档,该文档不能包含特定的iss值:相反,它包含一个占位符,在运行时始终将替换为您实际从中获取令牌的租户的颁发者标识符。 这意味着在多租户应用中,您必须接管租户验证逻辑。如果您只是调试,可以将其关闭,就像您似乎已经完成 - 这将阻止默认发行方验证逻辑启动并拒绝传入令牌,因为其iss值与找到的常用占位符不对应。但是,在更现实的情况下,您将在TokenValidationParameters.IssuerValidator委托中编写自己的逻辑。例如,您可能希望将传入令牌中的iss值与购买了每月订阅服务的租户列表进行比较。 HTH

答案 1 :(得分:0)

我在写这个问题时想到了这一点。我认为。但是我花了一整天的时间才发现这个问题几乎没有关于此事的文件,所以我想我还是会发布它。

我的解决方案(通过yet another blog post找到)是将ValidateIssuer = false作为参数包含在内。这是有道理的,因为我们不再需要验证给我们提供令牌的租户是我们列出的那个。

这是解决问题的代码。

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"],
                    ValidateIssuer = false // This line made it work
                },
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                Tenant = "common" // I don't know whether this has any impact,
                                  // but it's a required parameter regardless.
            });

如果有任何不可预见的情况,如果有其他人想要纠正我的话,我会很高兴 - 当您正在进行身份验证时,将“验证”切换为关闭是一件令人畏惧的事情。但我认为这一切都足够了。