我构建一个非常紧密跟随样品指导多租户MVC5应用:https://github.com/AzureADSamples/WebApp-MultiTenant-OpenIdConnect-DotNet/使用MVC授权与角色属性使用Azure的活动目录+ OWIN
我对认证Azure的Active Directory和有我自己的角色的名字,我的SecurityTokenvalidated活动期间注入的角色要求:
SecurityTokenValidated = (context) =>
{
// retriever caller data from the incoming principal
string upn = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.Name).Value;
string tenantId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
var databaseConnectionString = RoleEnvironment.GetConfigurationSettingValue("DatabaseConnectionString");
AppAnalyzerUser appAnalyzerUser = null;
using (CloudContext dbContext = new CloudContext(databaseConnectionString))
{
if (dbContext.Office365Accounts.FirstOrDefault(x => x.AzureTokenId == tenantId) == null)
throw new GeneralErrorException("Account not found", "The domain that you used to authenticate has not registered.");
appAnalyzerUser = (from au in dbContext.AppAnalyzerUsers
.Include(x => x.Roles)
where au.UserPrincipalName == upn && au.AzureTokenId == tenantId
select au).FirstOrDefault();
if (appAnalyzerUser == null)
throw new AccountNotFoundException();
}
foreach (var role in appAnalyzerUser.Roles)
{
Claim roleClaim = new Claim(ClaimTypes.Role, role.RoleName);
context.AuthenticationTicket.Identity.AddClaim(roleClaim);
}
return Task.FromResult(0);
},
我装修的一些方法与授权属性是这样的:
[Authorize(Roles = "SystemAdministrator"), HttpGet]
public ActionResult Index()
{
return View();
}
并且authorize属性正确检测到用户不在该角色中,并将它们发回Azure进行身份验证。
但是,我看到用户已经通过Azure AD的身份验证并登录到了该应用程序。他们没有机会在Azure屏幕上选择新的用户帐户来登录。因此,当它将它们反弹回Azure AD时,Azure AD会说“您已经登录”并将它们直接发送回应用程序。 SecurityTokenValidated事件反复激发,一遍又一遍。
但是用户仍然没有该方法所需的角色,因此他们会弹回到Azure进行身份验证,显然我们会陷入循环。
除了编写我自己的Authorize属性的实现,还有其他方法来解决这个问题吗?
谢谢。我最终编写了我自己的Authorize属性的实现,该属性抛出一个错误,我将它引导到一个解释性视图。 – ChrisW 2014-09-03 19:33:48