使用新组的 AD 组问题在云应用程序中的授权
Authorization in Cloud Applications using AD Groups issue with new group
我有一个 asp.net mvc 应用程序,我的代码基于这篇文章:http://www.dushyantgill.com/blog/2014/12/10/authorization-cloud-applications-using-ad-groups/
在此示例代码中:
https://github.com/dushyantgill/VipSwapper/tree/master/TrainingPoint
我为全局管理员创建了一个控制器
public class GlobalAdminController : Controller
{
// GET: GlobalAdmin
[AuthorizeUser(Roles = "admin")]
public ActionResult Index()
{
return View();
}
}
这是 startup.cs
public void ConfigureAuth(IAppBuilder app)
{
// configure the authentication type & settings
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// configure the OWIN OpenId Connect options
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = SettingsHelper.ClientId,
Authority = SettingsHelper.AzureADAuthority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
// we inject our own multitenant validation logic
ValidateIssuer = false,
// map the claimsPrincipal's roles to the roles claim
RoleClaimType = "roles",
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
// this allows you to deploy your app (to Azure Web Sites, for example) without having to change settings
// Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
//string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
context.ProtocolMessage.PostLogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
context.ProtocolMessage.Resource = SettingsHelper.GraphResourceId;
return Task.FromResult(0);
},
// when an auth code is received...
AuthorizationCodeReceived = (context) => {
// get the OpenID Connect code passed from Azure AD on successful auth
string code = context.Code;
// create the app credentials & get reference to the user
ClientCredential creds = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;
// use the ADAL to obtain access token & refresh token...
// save those in a persistent store...
EfAdalTokenCache sampleCache = new EfAdalTokenCache(userObjectId);
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority, sampleCache);
// obtain access token for the AzureAD graph
Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult authResult = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, creds, SettingsHelper.AzureAdGraphResourceId);
if (GraphUtil.IsUserAADAdmin(context.AuthenticationTicket.Identity))
context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", "admin"));
// successful auth
return Task.FromResult(0);
},
AuthenticationFailed = (context) => {
context.HandleResponse();
return Task.FromResult(0);
}
}
});
}
}
如果我使用组织的全局管理员中的用户登录,这将非常有效:
http://screencast.com/t/jLVNWGN7MgZR
但是我创建了另一个组并向该组添加了一个用户:
该组名为 Company Admin,用户为 companyadmin@
组
http://screencast.com/t/Y6vueAxjRPo
群组成员
http://screencast.com/t/BBRUoOxaD
然后我创建了另一个控制器:
public class CompanyAdminController : Controller
{
[AuthorizeUser(Roles = "company admin")]
public ActionResult Index()
{
return View();
}
}
我的家庭索引控制器操作中也有这个
public ActionResult Index()
{
if (User.IsInRole("admin"))
{
return RedirectToAction("Index", "GlobalAdmin");
}
if (User.IsInRole("company admin"))
{
return RedirectToAction("Index", "CompanyAdmin");
}
return View();
}
但是 User.IsInRole 对于公司管理员来说 return 不成立。
http://screencast.com/t/msVfvUt1g
更新 1
看起来该组确实在声明中 returned,只是看起来授权不正确或者我遗漏了一些代码。
Azure AD 中的组是主体(用户、服务、组)的集合。而 Azure AD 中的应用角色表示应用权限的集合。用户的组成员资格未出现在角色声明中。应用程序向 Azure AD 声明其角色(例如管理员、reader、编写器)。当一个组织 purchases/deploys 应用程序时,该组织的管理员可以将 users/groups/services 从他们的组织分配给应用程序的角色(例如 john@contoso.com -> 应用程序管理员,project1team 组 - > 应用程序的作者,所有用户组 -> reader 应用程序)。然后,当用户登录应用程序时,Azure AD 发出角色声明并指定分配给用户的所有应用程序角色(直接分配或通过组)。此处有更多详细信息:http://blogs.technet.com/b/ad/archive/2014/12/18/azure-active-directory-now-with-group-claims-and-application-roles.aspx
因此,对于您的示例,您似乎需要创建一个名为公司管理员的应用角色,并允许您的应用的客户将 users/groups 分配给该角色。
希望对您有所帮助。
我很好奇,您是否正在创建一个帮助管理 Azure AD 身份的应用程序?
由于 bluefeet 版主和 martij Pieters 版主删除了我的答案,答案中最重要的部分在 owin 管道上
var groups = GraphUtil.GetMemberGroups(context.AuthenticationTicket.Identity).Result;
//For each group, we have its, ID, we need to get the display name, and then we have to add the claim
foreach(string groupid in groups)
{
var displayname=GraphUtil.LookupDisplayNameOfAADObject(groupid, context.AuthenticationTicket.Identity);
context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", displayname));
}
但是Whosebug不允许超过30,000个字符,答案大约是45,000个字符,所以读者可以去这里查看完整的解释:
http://www.luisevalencia.com/2015/06/02/using-azure-aad-graph-office-365-add-in-with-groups-authorization/
我有一个 asp.net mvc 应用程序,我的代码基于这篇文章:http://www.dushyantgill.com/blog/2014/12/10/authorization-cloud-applications-using-ad-groups/
在此示例代码中: https://github.com/dushyantgill/VipSwapper/tree/master/TrainingPoint
我为全局管理员创建了一个控制器
public class GlobalAdminController : Controller
{
// GET: GlobalAdmin
[AuthorizeUser(Roles = "admin")]
public ActionResult Index()
{
return View();
}
}
这是 startup.cs
public void ConfigureAuth(IAppBuilder app)
{
// configure the authentication type & settings
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// configure the OWIN OpenId Connect options
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = SettingsHelper.ClientId,
Authority = SettingsHelper.AzureADAuthority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
// we inject our own multitenant validation logic
ValidateIssuer = false,
// map the claimsPrincipal's roles to the roles claim
RoleClaimType = "roles",
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
// This ensures that the address used for sign in and sign out is picked up dynamically from the request
// this allows you to deploy your app (to Azure Web Sites, for example) without having to change settings
// Remember that the base URL of the address used here must be provisioned in Azure AD beforehand.
//string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path);
context.ProtocolMessage.PostLogoutRedirectUri = new UrlHelper(HttpContext.Current.Request.RequestContext).Action("Index", "Home", null, HttpContext.Current.Request.Url.Scheme);
context.ProtocolMessage.Resource = SettingsHelper.GraphResourceId;
return Task.FromResult(0);
},
// when an auth code is received...
AuthorizationCodeReceived = (context) => {
// get the OpenID Connect code passed from Azure AD on successful auth
string code = context.Code;
// create the app credentials & get reference to the user
ClientCredential creds = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;
// use the ADAL to obtain access token & refresh token...
// save those in a persistent store...
EfAdalTokenCache sampleCache = new EfAdalTokenCache(userObjectId);
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.AzureADAuthority, sampleCache);
// obtain access token for the AzureAD graph
Uri redirectUri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult authResult = authContext.AcquireTokenByAuthorizationCode(code, redirectUri, creds, SettingsHelper.AzureAdGraphResourceId);
if (GraphUtil.IsUserAADAdmin(context.AuthenticationTicket.Identity))
context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", "admin"));
// successful auth
return Task.FromResult(0);
},
AuthenticationFailed = (context) => {
context.HandleResponse();
return Task.FromResult(0);
}
}
});
}
}
如果我使用组织的全局管理员中的用户登录,这将非常有效: http://screencast.com/t/jLVNWGN7MgZR
但是我创建了另一个组并向该组添加了一个用户: 该组名为 Company Admin,用户为 companyadmin@
组 http://screencast.com/t/Y6vueAxjRPo
群组成员 http://screencast.com/t/BBRUoOxaD
然后我创建了另一个控制器:
public class CompanyAdminController : Controller
{
[AuthorizeUser(Roles = "company admin")]
public ActionResult Index()
{
return View();
}
}
我的家庭索引控制器操作中也有这个
public ActionResult Index()
{
if (User.IsInRole("admin"))
{
return RedirectToAction("Index", "GlobalAdmin");
}
if (User.IsInRole("company admin"))
{
return RedirectToAction("Index", "CompanyAdmin");
}
return View();
}
但是 User.IsInRole 对于公司管理员来说 return 不成立。 http://screencast.com/t/msVfvUt1g
更新 1
看起来该组确实在声明中 returned,只是看起来授权不正确或者我遗漏了一些代码。
Azure AD 中的组是主体(用户、服务、组)的集合。而 Azure AD 中的应用角色表示应用权限的集合。用户的组成员资格未出现在角色声明中。应用程序向 Azure AD 声明其角色(例如管理员、reader、编写器)。当一个组织 purchases/deploys 应用程序时,该组织的管理员可以将 users/groups/services 从他们的组织分配给应用程序的角色(例如 john@contoso.com -> 应用程序管理员,project1team 组 - > 应用程序的作者,所有用户组 -> reader 应用程序)。然后,当用户登录应用程序时,Azure AD 发出角色声明并指定分配给用户的所有应用程序角色(直接分配或通过组)。此处有更多详细信息:http://blogs.technet.com/b/ad/archive/2014/12/18/azure-active-directory-now-with-group-claims-and-application-roles.aspx
因此,对于您的示例,您似乎需要创建一个名为公司管理员的应用角色,并允许您的应用的客户将 users/groups 分配给该角色。
希望对您有所帮助。
我很好奇,您是否正在创建一个帮助管理 Azure AD 身份的应用程序?
由于 bluefeet 版主和 martij Pieters 版主删除了我的答案,答案中最重要的部分在 owin 管道上
var groups = GraphUtil.GetMemberGroups(context.AuthenticationTicket.Identity).Result;
//For each group, we have its, ID, we need to get the display name, and then we have to add the claim
foreach(string groupid in groups)
{
var displayname=GraphUtil.LookupDisplayNameOfAADObject(groupid, context.AuthenticationTicket.Identity);
context.AuthenticationTicket.Identity.AddClaim(new Claim("roles", displayname));
}
但是Whosebug不允许超过30,000个字符,答案大约是45,000个字符,所以读者可以去这里查看完整的解释: http://www.luisevalencia.com/2015/06/02/using-azure-aad-graph-office-365-add-in-with-groups-authorization/