我最近开始使用Azure Active Directory来根据我在AngularJS上构建的网站对用户进行身份验证。
使用博客和sample code on GitHub,我已经使用ADAL.js和Katana Bearer Token AD integration的组合使用单租户。
但是,我现在遇到一些支持多个租户的问题。
我有一个页面设置,显示用户ADAL看到它们(通过根范围的userInfo
找到),并调用我的服务器,被OWIN接收,并序列化context.Authentication.User
。
客户端,一切似乎都正常。我可以使用我的任何租户登录,它会为我提供我期望的对象(填充isAuthenticated: true
,username
,以及描述用户的profile
上的各种属性,登录和租户)。
这是在客户端完成的,方法是将tenant
参数留给adalAuthenticationServiceProvider.init
调用,如文档中所述。
UseWindowsAzureActiveDirectoryBearerAuthentication
方法不喜欢Tenant
没有值(因为它会引发异常)。我已经为此尝试了一些值,包括我的应用最初注册的租户,以及我的逻辑最喜欢的“常见”,但无论我放在那里(除非是我试图登录的租户)如果我的ADAL与该租户一起设置,那么它似乎只是跳过这个。
对于它的价值,实际的API调用在[Authorize]
过滤器上失败并返回401,这告诉我这不是我的OWIN拦截器的问题。
如何判断UseWindowsAzureActiveDirectoryBearerAuthentication
是否支持多租户身份验证?
答案 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.
});
如果有任何不可预见的情况,如果有其他人想要纠正我的话,我会很高兴 - 当您正在进行身份验证时,将“验证”切换为关闭是一件令人畏惧的事情。但我认为这一切都足够了。