Asp 使用 Active Directory 的网络核心 MVC 授权
Asp net core MVC Authorization with Active Directory
在 Asp net core MVC 应用程序中,我使用 Active Directory 进行自动登录,如下所示:
this.user = UserPrincipal.FindByIdentity(this.context, Environment.UserName);
我得到了用户组:
public List<String> GetUserGroups()
{
List<String> groups = new List<String>();
foreach(GroupPrincipal gr in user.GetGroups())
{
groups.Add(gr.Name);
}
return groups;
}
我想用这个组实现 Autorisation,类似的东西:
[Authorize(Roles ="Admin")]
public IActionResult OnlyAdmin(){}
使用 link 具有授权角色的 AD 组,或者如果可能的话直接检查 AD 组的授权,但我不知道如何做这样的事情。
注意:我没有任何 login/logout 页,它只是自动的。
编辑
不知道确切的原因或方式,但它最终在没有任何代码的情况下工作,并且只有在 PC 中的用户登录而不是 this.user
中指定的用户,但这样很好。
但现在我在尝试访问被拒绝的页面时收到 404 错误,为什么它不是 401 或 403 错误?如何将被拒绝的访问重定向到自定义错误页面?
您需要在 ClaimsPrincipal class 中添加组,即
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, username));
foreach (string userGroup in authResponse)
{
claims.Add(new Claim(ClaimTypes.Role, userGroup, ClaimValueTypes.String,"system","system"));
}
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "authenticationScheme"));
现在在控制器或操作上使用授权属性:
[Authorize(Roles = "guest,home")]
你可以写一个ErrorHandlingMiddleware,如下所示。您需要在启动文件中注册它
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
以下是相同的示例。
public class 错误处理中间件
{
私人只读 RequestDelegate _next;
私人只读 ILogger _logger;
public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> createLogger)
{
this._next = next;
this._logger = createLogger;
}
public async Task Invoke(HttpContext context)
{
var statusCode = HttpStatusCode.OK;
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
this._logger.LogError(ex, ex.Message);
switch (context.Response.StatusCode)
{
case (int)HttpStatusCode.NotFound:
statusCode = HttpStatusCode.NotFound;
break;
case (int)HttpStatusCode.Forbidden:
statusCode = HttpStatusCode.Forbidden;
break;
case (int)HttpStatusCode.BadRequest:
statusCode = HttpStatusCode.BadRequest;
break;
default:
statusCode = HttpStatusCode.InternalServerError;
break;
}
context.Response.StatusCode = (int)statusCode;
}
if (!context.Response.HasStarted)
{
context.Response.ContentType = "application/json";
var response = new { code = statusCode };
var json = JsonConvert.SerializeObject(response);
await context.Response.WriteAsync(json);
}
}
}
在 Asp net core MVC 应用程序中,我使用 Active Directory 进行自动登录,如下所示:
this.user = UserPrincipal.FindByIdentity(this.context, Environment.UserName);
我得到了用户组:
public List<String> GetUserGroups()
{
List<String> groups = new List<String>();
foreach(GroupPrincipal gr in user.GetGroups())
{
groups.Add(gr.Name);
}
return groups;
}
我想用这个组实现 Autorisation,类似的东西:
[Authorize(Roles ="Admin")]
public IActionResult OnlyAdmin(){}
使用 link 具有授权角色的 AD 组,或者如果可能的话直接检查 AD 组的授权,但我不知道如何做这样的事情。
注意:我没有任何 login/logout 页,它只是自动的。
编辑
不知道确切的原因或方式,但它最终在没有任何代码的情况下工作,并且只有在 PC 中的用户登录而不是 this.user
中指定的用户,但这样很好。
但现在我在尝试访问被拒绝的页面时收到 404 错误,为什么它不是 401 或 403 错误?如何将被拒绝的访问重定向到自定义错误页面?
您需要在 ClaimsPrincipal class 中添加组,即
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, username));
foreach (string userGroup in authResponse)
{
claims.Add(new Claim(ClaimTypes.Role, userGroup, ClaimValueTypes.String,"system","system"));
}
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "authenticationScheme"));
现在在控制器或操作上使用授权属性:
[Authorize(Roles = "guest,home")]
你可以写一个ErrorHandlingMiddleware,如下所示。您需要在启动文件中注册它
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
以下是相同的示例。 public class 错误处理中间件 { 私人只读 RequestDelegate _next; 私人只读 ILogger _logger;
public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> createLogger)
{
this._next = next;
this._logger = createLogger;
}
public async Task Invoke(HttpContext context)
{
var statusCode = HttpStatusCode.OK;
try
{
await _next.Invoke(context);
}
catch (Exception ex)
{
this._logger.LogError(ex, ex.Message);
switch (context.Response.StatusCode)
{
case (int)HttpStatusCode.NotFound:
statusCode = HttpStatusCode.NotFound;
break;
case (int)HttpStatusCode.Forbidden:
statusCode = HttpStatusCode.Forbidden;
break;
case (int)HttpStatusCode.BadRequest:
statusCode = HttpStatusCode.BadRequest;
break;
default:
statusCode = HttpStatusCode.InternalServerError;
break;
}
context.Response.StatusCode = (int)statusCode;
}
if (!context.Response.HasStarted)
{
context.Response.ContentType = "application/json";
var response = new { code = statusCode };
var json = JsonConvert.SerializeObject(response);
await context.Response.WriteAsync(json);
}
}
}