对于我的学习,我必须实现一个自定义AuthorizeAttribute,以允许或不允许用户根据其角色(admin,manager,...)访问应用程序的各个部分。我使用自己的SQL DB。
请您帮我理解为什么即使用户登录也会重定向到LoginView? 我在网上搜索了很多,但没有找到任何解决方案。
的Web.config:
<authentication mode="Forms">
<forms loginUrl="~/Authentication/Login" timeout="2880" />
</authentication>
AuthenticationController:
public class AuthenticationController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
public ActionResult Login(User user, string returnUrl)
{
if (ModelState.IsValid)
{
if (IsValid(user.Email, user.Password))
{
FormsAuthentication.SetAuthCookie(user.Email, true);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Incorrect Email or Password.");
return View(user);
}
}
return View(user);
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
private bool IsValid(string email, string password)
{
var crypto = new SimpleCrypto.PBKDF2();
bool isValid = false;
using (var dBContext = new DBContext())
{
var user = dBContext.Users.FirstOrDefault(u => u.Email == email);
if (user!=null)
{
if (user.Password == crypto.Compute(password, user.saltedPassword))
{
isValid = true;
}
}
}
return isValid;
}
}
HomeController中:
public class HomeController : Controller
{
[CustomAuthorize(Roles = "Admin,Manager,...")]
public ActionResult Index()
{
return View();
}
}
过滤器:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public CustomAuthorizeAttribute() { }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAuthenticated)
return false;
DBContext dBContext = new DBContext();
var roleList = from r in dBContext.Roles
join rl in dBContext.RoleLists on r.RoleId equals rl.RoleId
join s in dBContext.Subscriptions on rl.SubscriptionId equals s.SubscriptionId
join u in dBContext.Users on s.UserId equals u.UserId
where u.Email == httpContext.User.Identity.Name
select r.RoleName;
foreach (string definedRole in this.Roles.Split(','))
{
foreach (string role in roleList)
{
if (definedRole.Equals(role))
{
return true;
}
}
}
return false;
}
一个FilterConfig:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizeAttribute());
filters.Add(new HandleErrorAttribute());
}
}
修改以添加更多信息:
如果我使用AuthorizeCore()的返回值为true: 在foreach的第一次迭代中,.Roles并没有包含已定义的角色,但在第二次迭代中......系统显示所请求的视图而不考虑定义的角色。
如果我使用AuthorizeCore()作为返回值false: 第一个foreach的迭代只发生一次而且this.Roles不包含定义的角色,第二个foreach比较用户的角色和#34; &#34; ...系统显示LoginView。
答案 0 :(得分:0)
我通过评论此行解决了问题:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new CustomAuthorizeAttribute());
filters.Add(new HandleErrorAttribute());
}
}
现在,已登录用户的角色与
中定义的角色进行了比较[CustomAuthorize(Roles =&#34; Admin,Manager,...&#34;)]
应用程序显示请求的视图,除非用户没有权利。