为了这个目的,我有AllowFor属性。它看起来像:
public class AllowFor : ActionFilterAttribute
{
private UserType userTypes = UserType.NotAuthenticated;
public AllowFor(UserType userTypes)
{
this.userTypes = userTypes;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!(filterContext.Controller is ApplicationController))
throw new Exception("AllowFor attribute is acceptable only for ApplicationController");
var controller = (ApplicationController)filterContext.Controller;
if (!userTypes.HasFlag(controller.CurrentUserType))
filterContext.Result = new ViewResult
{
ViewName = "AccessRestricted"
};
else
base.OnActionExecuting(filterContext);
}
}
ApplicationController只是我的类继承自Contoller。
public abstract class Application : Controller
{
public UserType CurrentUserType
{
get
{
return currentUser.UserType;
}
}
// singleton for current user
protected User __currentUser = null;
protected User currentUser
{
get
{
if (__currentUser == null && HttpContext != null && HttpContext.User.Identity.IsAuthenticated)
{
// access to sql based on:
// HttpContext.User.Identity.IsAuthenticated
// HttpContext.User.Identity.Name
// etc
}
return __currentUser;
}
}
// singleton for EF context
private MyAppContext __context = null;
protected MyAppContext context
{
get
{
if (__context == null)
{
__context = new MyAppContext();
}
return __context;
}
}
}
实际上并不需要它,但我觉得它非常有用。只需从ApplicationContoller继承你的控制器,你就可以用单例模式检索上下文和其他对象。
属性的使用方法十分简单,只需标记你的动作与属性:
[Authorize, AllowFor(UserType.Company)]
public ActionResult Index()
{
// ...
}
你可以让你AllowFor属性更加有用,它适用于类(控制器,例如),而不是动作:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
public class AllowFor : ActionFilterAttribute { ... }
如果你想获取基于表单的身份验证数据库的用户,你可以按照以下两种方法之一:
这是很容易通过电子邮件获取,但这种方法有几个缺点取:
- 你必须确保你的会员资格供应商需要独特的电子邮件地址(必须设置你的会员提供的
requiresUniqueEmail
财产Web.config
到true
)
例:
<membership defaultProvider="MyMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="MyMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MembershipConnection" applicationName="GeekJob" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="1" maxInvalidPasswordAttempts="100" passwordAttemptWindow="1440" />
</providers>
</membership>
你必须记住,[email protected]
不[email protected]
。如果您需要通过电子邮件从数据库中提取用户,则表格中必须有其他列LoweredEmail
。此外,请不要忘记LoweredEmail
列中的表格索引。此外,不要忘记用[StringLength(450)]
属性标记它(如果您使用MS SQL Server,因为如果您在其上应用索引,字符串列不能超过450个Unicode符号)。
如果用户决定更改他的电子邮件会怎么样?您需要修改成员资格和实体表。听起来像我们正在前往code smell。
因此,我建议对ProviderUserKey
资源相关联的会员和现有表(你还需要额外的列和索引)。
现在,您可以通过方便抓取用户:
if (HttpContext != null && HttpContext.User.Identity.IsAuthenticated)
{
MembershipUser mu = Membership.GetUser(HttpContext.User.Identity.Name);
return context.Users.Where(u => u.UserKey == (Guid)mu.ProviderUserKey).FirstOrDefault();
}
因此,我的下一个问题是,我怎么会知道用户什么工程公司? 我需要使用他的电子邮件/用户保存使用表单身份验证cookie,然后从数据库池? – LmC
谢谢,我更新了帖子,看看。 –
你如何使用你的应用程序:控制器?我是否继承我的所有控制器首页:应用程序? – LmC