从 Active Directory 进行身份验证,但从 MVC 中的 SQL 数据库授权角色
Authenticate from Active Directory but Authorize Roles from SQL Database in MVC
我是 MVC 新手。我搜索并没有找到适合我要求的解决方案。
我正在开发一个供我们团队内部使用的 Web 门户,它使用 Windows AD 身份验证进行登录。但是,对于基于角色的访问,我创建了一个本地数据库,它可以 return 用户的角色详细信息。
我创建了一个自定义授权过滤器,允许我根据用户的角色处理授权。此过滤器正在从数据库中查询详细信息,但是这种方法的问题是,它会尝试从数据库中获取对控制器的每个请求的详细信息,这使得它变得昂贵。
如何将从数据库中获取的用户详细信息保存在令牌中,这样我就不必为每个请求查询数据库并在授权过滤器中使用令牌值。此外,我可以在应用程序的任何其他位置使用从数据库中为用户检索的值。 (我们在数据库中拥有该用户的一些其他详细信息)。
如果有人可以提出更好的实现方法,请帮忙。
这是我目前在授权过滤器中使用的代码:
public class AuthorizeRole : AuthorizeAttribute
{
private bool _authenticated;
private bool _authorized;
public string InRoles { get; set; }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
if (_authenticated && !_authorized)
{
filterContext.Result = new RedirectResult("/account/error");
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
_authenticated = base.AuthorizeCore(httpContext);
if (_authenticated)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
_authorized = false;
return _authorized;
}
}
请建议在哪个部分使用您建议的代码(例如,在控制器内部、过滤器内部或其他地方。)
我在 this site 找到了这个解决方案,但它用于 AD 组。
首先,您可能想看看使用 AD 安全组来管理访问。这样 OPS 可以继续在熟悉的经过时间考验的平台中保持访问,而您不必编写自己的安全定义接口。
关于 MVC 安全持久性
您所要做的就是添加一个手动登录来执行上述逻辑,然后使用内置的成员资格提供程序(对于您使用的任何版本的 MVC)让用户登录。MVC 将处理维护登录状态并为您标记化,您可以在 web.config(或核心中的 settings.json)中指定诸如超时之类的内容。
抱歉,我手边没有任何示例代码可用于说明。
我已经在方法 AuthorizeCore
的覆盖版本中检查了 cookie,它现在正在工作:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = httpContext.Request.Cookies[cookieName];
_authenticated = base.AuthorizeCore(httpContext);
string authToken = httpContext.Request.Headers["Auth-Token"];
if (_authenticated)
{
if (authCookie == null)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
_authorized = true;
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
}
_authorized = false;
return _authorized;
}
我是 MVC 新手。我搜索并没有找到适合我要求的解决方案。
我正在开发一个供我们团队内部使用的 Web 门户,它使用 Windows AD 身份验证进行登录。但是,对于基于角色的访问,我创建了一个本地数据库,它可以 return 用户的角色详细信息。 我创建了一个自定义授权过滤器,允许我根据用户的角色处理授权。此过滤器正在从数据库中查询详细信息,但是这种方法的问题是,它会尝试从数据库中获取对控制器的每个请求的详细信息,这使得它变得昂贵。
如何将从数据库中获取的用户详细信息保存在令牌中,这样我就不必为每个请求查询数据库并在授权过滤器中使用令牌值。此外,我可以在应用程序的任何其他位置使用从数据库中为用户检索的值。 (我们在数据库中拥有该用户的一些其他详细信息)。
如果有人可以提出更好的实现方法,请帮忙。
这是我目前在授权过滤器中使用的代码:
public class AuthorizeRole : AuthorizeAttribute
{
private bool _authenticated;
private bool _authorized;
public string InRoles { get; set; }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
if (_authenticated && !_authorized)
{
filterContext.Result = new RedirectResult("/account/error");
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
_authenticated = base.AuthorizeCore(httpContext);
if (_authenticated)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
_authorized = false;
return _authorized;
}
}
请建议在哪个部分使用您建议的代码(例如,在控制器内部、过滤器内部或其他地方。)
我在 this site 找到了这个解决方案,但它用于 AD 组。
首先,您可能想看看使用 AD 安全组来管理访问。这样 OPS 可以继续在熟悉的经过时间考验的平台中保持访问,而您不必编写自己的安全定义接口。
关于 MVC 安全持久性 您所要做的就是添加一个手动登录来执行上述逻辑,然后使用内置的成员资格提供程序(对于您使用的任何版本的 MVC)让用户登录。MVC 将处理维护登录状态并为您标记化,您可以在 web.config(或核心中的 settings.json)中指定诸如超时之类的内容。
抱歉,我手边没有任何示例代码可用于说明。
我已经在方法 AuthorizeCore
的覆盖版本中检查了 cookie,它现在正在工作:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = httpContext.Request.Cookies[cookieName];
_authenticated = base.AuthorizeCore(httpContext);
string authToken = httpContext.Request.Headers["Auth-Token"];
if (_authenticated)
{
if (authCookie == null)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
_authorized = true;
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
}
_authorized = false;
return _authorized;
}