gpt4 book ai didi

c# - `[Authorize(Roles = "管理 ")]` 无限循环 ASP.NET MVC 和 Azure Active Directory B2C

转载 作者:太空宇宙 更新时间:2023-11-03 22:48:54 24 4
gpt4 key购买 nike

我尝试仅允许具有“全局管理员”角色的 Azure Active Directory B2C 用户访问以下类(这就是我包含 Authorize 命令的原因):

[Authorize(Roles = "admin")]
public class UserProfileController : Controller
{
... controller class ...
}

我的 Startup 类如下所示:

public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
// This is the resource ID of the AAD Graph API. We'll need this to request a token to call the Graph API.
private static string graphResourceId = "https://graph.microsoft.com";
private static readonly string Authority = aadInstance + tenantId;
public static GraphServiceClient graphClient = null;

public static GraphServiceClient GetGraphServiceClient()
{
return graphClient;
}

public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
CookieSecure = CookieSecureOption.Always
});

app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
PostLogoutRedirectUri = postLogoutRedirectUri,

Notifications = new OpenIdConnectAuthenticationNotifications()
{
// If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;

TokenCache userTokenCache = new ADALTokenCache(signedInUserID);

AuthenticationContext authContext = new AuthenticationContext(Authority, userTokenCache);
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);

string token = result.AccessToken;

try
{
graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);

return Task.FromResult(0);
}));
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Failed to create graph client: " + e.Message);
}

return Task.FromResult(0);
}
}
});
}
}

问题是:当我单击实例化 UserProfileController 的按钮时,AuthorizationCodeReceived = (context) => 代码行中的代码会被一次又一次调用无限循环。如何修复无限循环,以便只有 Azure Active Directory B2C“全局管理员”可以实例化 UserProfileController?

最佳答案

[Authorize(Roles = "admin")]

由于您使用授权属性来检查用户的角色,因此您需要确保当前用户的声明具有有效的角色声明。您可以利用以下代码片段来检查您当前的用户声明:

return Json((User.Identity as ClaimsIdentity).Claims.Select(c => new { key = c.Type, value = c.Value }),JsonRequestBehavior.AllowGet);

The problem is: when I click on the button that instantiates the UserProfileController, then the the code inside of AuthorizationCodeReceived = (context) => line of code is called again and again in an infinite loop.

您可以覆盖 HandleUnauthorizedRequest AuthorizeAttribute下的方法并定义您的自定义授权属性,如下所示:

public class MyAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
filterContext.Result = new ContentResult() { Content = "You don't have rights to take actions" };
}
}

然后,你可以装饰你的 UserProfileController Controller 如下:

[MyAuthorize(Roles = "admin")]
public class UserProfileController : Controller
{
//TODO:
}

I am attempting to allow only Azure Active Directory B2C users with role "Global Administrator" to access the following class

根据AuthorizationCodeReceived委托(delegate)方法,检索访问 token 后,需要利用 Microsoft Graph 客户端库检查当前用户是否是全局管理员/公司管理员。如果当前用户是全局管理员/公司管理员,则需要指定角色声明,如下所示:

context.AuthenticationTicket.Identity.AddClaim(new Claim(context.AuthenticationTicket.Identity.RoleClaimType, "admin"));

注意:要检查用户是否为全局管理员,您可以检索当前用户目录下的角色,然后使用 getMemberObjects API 检索当前用户所属的组、角色,然后检查全局管理员角色 id 是否在当前用户的 MemberObjects 中。

//List directory roles, https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/directoryrole_list
var roles=await graphClient.DirectoryRoles.Request().GetAsync();

//user: getMemberObjects ,https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_getmemberobjects

更新:

我检查了我这边的实现。以下是检查当前登录用户的角色的代码。

var directoryRoles = await graphClient.DirectoryRoles.Request().GetAsync();
var userRoles = await graphClient.Me.MemberOf.Request().GetAsync();

var adminRole=directoryRoles.Where(role => role.DisplayName== "Company Administrator" || role.DisplayName == "Global Administrator").FirstOrDefault();
if (userRoles.Count(role => role.Id == adminRole.Id) > 0)
{
context.AuthenticationTicket.Identity.AddClaim(new Claim(context.AuthenticationTicket.Identity.RoleClaimType, "admin"));
}
else
{
context.AuthenticationTicket.Identity.AddClaim(new Claim(context.AuthenticationTicket.Identity.RoleClaimType, "user"));
}

注意:要添加多个用户角色,您可以添加多个 new Claim(context.AuthenticationTicket.Identity.RoleClaimType, "<role-name>")角色声明。

这是我修改后的自定义AuthorizeAttribute :

public class MyAuthorize : AuthorizeAttribute
{
private bool noPermission = false;

public string Permissions { get; set; }

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!base.AuthorizeCore(httpContext))
return false;

var permissionArrs = Permissions.Trim().Split('|');

if (permissionArrs.ToList().Exists(p=>httpContext.User.IsInRole(p)))
{
return true;
}
else
{
noPermission = true;
return false;
}
}

protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
if (noPermission)
filterContext.Result = new ContentResult() { Content = "You don't have rights to take actions" };
else
base.HandleUnauthorizedRequest(filterContext);
}
}

装饰UserProfileController如下:

[MyAuthorize(Permissions = "admin|co-admin")]
public class UsersController : Controller
{
//TODO:
}

关于c# - `[Authorize(Roles = "管理 ")]` 无限循环 ASP.NET MVC 和 Azure Active Directory B2C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48531433/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com