Azure AD 应用程序角色
Azure AD application roles
我正在尝试通过 Azure AD 应用程序角色创建受保护的控制器。
这里免除Startup.Auth,基本由Visual Studio模板提供:
public void ConfigureAuth(IAppBuilder app)
{
ApplicationDbContext db = new ApplicationDbContext();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
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;
AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
return Task.FromResult(0);
}
}
});
}
尝试过具有如下属性的 ApiController:
[Authorize(Roles = "Administrators")]
// GET: api/Questions
[ResponseType(typeof(Question))]
public IHttpActionResult GetQuestions()
{
....
}
和一个 MVC 控制器:
[Authorize(Roles = "Administrators")]
public ActionResult Index()
{
....
}
在 Azure 应用程序清单中定义了以下内容:
"appRoles": [
{
"id": "B4531A9A-0DC8-4015-8CE5-CA1DA1D73754",
"allowedMemberTypes": ["User"],
"description": "Administrators",
"displayName": "Administrators",
"value": "Administrators",
"isEnabled": true,
"origin": "Application"
}
]
现在执行 /api/Questions 的 GET 请求重定向到 https://login.microsoftonline.com 并且用户身份验证似乎成功,此外本地主机和 Microsoft 在线之间存在无限循环的请求。见下文:
我做错了什么?
使用 [Authorize] 就可以了。
原来应该将以下内容添加到 Startup.Auth:
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
// map the claimsPrincipal's roles to the roles claim
RoleClaimType = "roles",
}
它实际上是在配置 'roles' 声明类型,以便将其映射到默认行为。
优秀的解释可在:
https://samlman.wordpress.com/2015/03/09/using-roles-in-azure-applications/
对我来说,上面的解决方案没有用。相反,我实现了自定义 AuthorizeAttribute
,如 https://identityserver.github.io/Documentation/docs/overview/mvcGettingStarted.html 中所述,以避免无限重定向循环。
这是我的自定义 AuthorizeAttribute
实现代码(同样,主要来自上面的资源):
public class RoleAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// If the user is authenticated, but we ended up here, it means that
// the user is not in a role that's allowed to use the controller being called
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
else
filterContext.Result = new HttpUnauthorizedResult();
}
}
PS:我不包括 TokenValidationParameters
代码,我可以使用指定和不指定 Roles
的 AuthorizeAttribute
。但是,当我指定 Authorize(Roles = "SomeRole")
并且已经通过身份验证和授权的用户不在该角色中时,我将面临无限重定向循环。
因此,对于那些我必须使用基于角色的授权的控制器方法,我改用 RoleAuthorize(Roles = "SomeRole")
。我还有一个自定义 403 错误页面,其样式与应用程序相似,并提供适当数量的详细信息并注销 link,以便用户可以尝试以其他用户身份进行身份验证。
我对该解决方案并不完全满意,因为我认为内置的 AuthorizeAttribute
应该能够处理这种情况。我只是无法让它工作。
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.Request.Url.IsLoopback)
{
return true;
}
return base.AuthorizeCore(httpContext);
}
以上代码旨在消除本地主机调用。希望它对你有用。
我正在尝试通过 Azure AD 应用程序角色创建受保护的控制器。
这里免除Startup.Auth,基本由Visual Studio模板提供:
public void ConfigureAuth(IAppBuilder app)
{
ApplicationDbContext db = new ApplicationDbContext();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
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;
AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
return Task.FromResult(0);
}
}
});
}
尝试过具有如下属性的 ApiController:
[Authorize(Roles = "Administrators")]
// GET: api/Questions
[ResponseType(typeof(Question))]
public IHttpActionResult GetQuestions()
{
....
}
和一个 MVC 控制器:
[Authorize(Roles = "Administrators")]
public ActionResult Index()
{
....
}
在 Azure 应用程序清单中定义了以下内容:
"appRoles": [
{
"id": "B4531A9A-0DC8-4015-8CE5-CA1DA1D73754",
"allowedMemberTypes": ["User"],
"description": "Administrators",
"displayName": "Administrators",
"value": "Administrators",
"isEnabled": true,
"origin": "Application"
}
]
现在执行 /api/Questions 的 GET 请求重定向到 https://login.microsoftonline.com 并且用户身份验证似乎成功,此外本地主机和 Microsoft 在线之间存在无限循环的请求。见下文:
我做错了什么?
使用 [Authorize] 就可以了。
原来应该将以下内容添加到 Startup.Auth:
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
// map the claimsPrincipal's roles to the roles claim
RoleClaimType = "roles",
}
它实际上是在配置 'roles' 声明类型,以便将其映射到默认行为。 优秀的解释可在: https://samlman.wordpress.com/2015/03/09/using-roles-in-azure-applications/
对我来说,上面的解决方案没有用。相反,我实现了自定义 AuthorizeAttribute
,如 https://identityserver.github.io/Documentation/docs/overview/mvcGettingStarted.html 中所述,以避免无限重定向循环。
这是我的自定义 AuthorizeAttribute
实现代码(同样,主要来自上面的资源):
public class RoleAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// If the user is authenticated, but we ended up here, it means that
// the user is not in a role that's allowed to use the controller being called
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden);
else
filterContext.Result = new HttpUnauthorizedResult();
}
}
PS:我不包括 TokenValidationParameters
代码,我可以使用指定和不指定 Roles
的 AuthorizeAttribute
。但是,当我指定 Authorize(Roles = "SomeRole")
并且已经通过身份验证和授权的用户不在该角色中时,我将面临无限重定向循环。
因此,对于那些我必须使用基于角色的授权的控制器方法,我改用 RoleAuthorize(Roles = "SomeRole")
。我还有一个自定义 403 错误页面,其样式与应用程序相似,并提供适当数量的详细信息并注销 link,以便用户可以尝试以其他用户身份进行身份验证。
我对该解决方案并不完全满意,因为我认为内置的 AuthorizeAttribute
应该能够处理这种情况。我只是无法让它工作。
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.Request.Url.IsLoopback)
{
return true;
}
return base.AuthorizeCore(httpContext);
}
以上代码旨在消除本地主机调用。希望它对你有用。