如何为ASP创建自定义成员资格.NETMVC2基于ASP.网络会员Provider ?

推荐答案

我已经创建了一个包含自定义成员资格提供程序的新项目,并覆盖了MembershipProvider抽象类中的ValidateUser方法:

public class MyMembershipProvider : MembershipProvider
{ 
    public override bool ValidateUser(string username, string password)
    {    
        // this is where you should validate your user credentials against your database.
        // I've made an extra class so i can send more parameters 
        // (in this case it's the CurrentTerritoryID parameter which I used as 
        // one of the MyMembershipProvider class properties). 

        var oUserProvider = new MyUserProvider();  
        return oUserProvider.ValidateUser(username,password,CurrentTerritoryID);
    }
}

然后我将该Provider 连接到我的ASP.NET MVC 2项目,添加一个参考并从我的网站上指出它.配置:

<membership defaultProvider="MyMembershipProvider">
    <providers>
        <clear />
        <add name="MyMembershipProvider"
            applicationName="MyApp"
            Description="My Membership Provider"
            passwordFormat="Clear"
            connectionStringName="MyMembershipConnection"
            type="MyApp.MyMembershipProvider" />
    </providers>
</membership>

我确实需要创建一个自定义类来继承RoleProvider抽象类并重写GetRolesForUser方法.

以下是我们需要采取的步骤:

1) 创建一个自定义类,该类继承RoleProvider抽象类并重写GetRolesForUser方法:

public override string[] GetRolesForUser(string username)
{
    SpHelper db = new SpHelper();
    DataTable roleNames = null;
    try
    {
        // get roles for this user from DB...

        roleNames = db.ExecuteDataset(ConnectionManager.ConStr,
                    "sp_GetUserRoles",
                    new MySqlParameter("_userName", username)).Tables[0];
    }
    catch (Exception ex)
    {
        throw ex;
    }
    string[] roles = new string[roleNames.Rows.Count];
    int counter = 0;
    foreach (DataRow row in roleNames.Rows)
    {
        roles[counter] = row["Role_Name"].ToString();
        counter++;
    }
    return roles;
}

2)通过我们的web.config将角色提供程序与ASP.NET MVC 2应用程序连接:

<system.web>
...

<roleManager enabled="true" defaultProvider="MyRoleProvider">
    <providers>
        <clear />
        <add name="MyRoleProvider"
            applicationName="MyApp"
            type="MyApp.MyRoleProvider"
            connectionStringName="MyMembershipConnection" />
    </providers>
</roleManager>

...
</system.web>

3)将Authorize(Roles="xxx,yyy")设置在想要的控制器/操作之上:

[Authorization(Roles = "Customer Manager,Content Editor")]
public class MyController : Controller
{
    ...... 
}

就这样!现在它起作用了!

4) 可选:设置自定义Authorize属性,以便将不需要的角色重定向到AccessDenied页面:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class MyAuthorizationAttribute : AuthorizeAttribute
{
    /// <summary>
    /// The name of the master page or view to use when rendering the view on authorization failure.  Default
    /// is null, indicating to use the master page of the specified view.
    /// </summary>
    public virtual string MasterName { get; set; }

    /// <summary>
    /// The name of the view to render on authorization failure.  Default is "Error".
    /// </summary>
    public virtual string ViewName { get; set; }

    public MyAuthorizationAttribute ()
        : base()
    {
        this.ViewName = "Error";
    }

    protected void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (AuthorizeCore(filterContext.HttpContext))
        {
            SetCachePolicy(filterContext);
        }
        else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // auth failed, redirect to login page
            filterContext.Result = new HttpUnauthorizedResult();
        }
        else if (filterContext.HttpContext.User.IsInRole("SuperUser"))
        {
            // is authenticated and is in the SuperUser role
            SetCachePolicy(filterContext);
        }
        else
        {
            ViewDataDictionary viewData = new ViewDataDictionary();
            viewData.Add("Message", "You do not have sufficient privileges for this operation.");
            filterContext.Result = new ViewResult { MasterName = this.MasterName, ViewName = this.ViewName, ViewData = viewData };
        }
    }

    protected void SetCachePolicy(AuthorizationContext filterContext)
    {
        // ** IMPORTANT **
        // Since we're performing authorization at the action level, the authorization code runs
        // after the output caching module. In the worst case this could allow an authorized user
        // to cause the page to be cached, then an unauthorized user would later be served the
        // cached page. We work around this by telling proxies not to cache the sensitive page,
        // then we hook our custom authorization code into the caching mechanism so that we have
        // the final say on whether a page should be served from the cache.
        HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
        cachePolicy.SetProxyMaxAge(new TimeSpan(0));
        cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
    }
}

现在,我们可以使用自己的made属性将用户重定向到拒绝访问的视图:

[MyAuthorization(Roles = "Portal Manager,Content Editor", ViewName = "AccessDenied")]
public class DropboxController : Controller
{ 
    .......
}

就这样! 超级高手!

以下是我用来获取这些信息的一些链接:

自定义角色提供程序:

我希望这些信息能有所帮助!

Asp.net相关问答推荐

502 DotNet WebApplication的网关nginx已损坏

使用 Asp.Net MVC 和 KnockoutJS 处理日期

.Net Framework:w3wp.exe 中的异常

在 aspx 页面中使用 if else 和 eval

ASP MVC 授权除少数之外的所有操作

ReportViewer 控件 - 高度问题

如何获取已构建、编码的 ViewState 的值?

使用 C# 和 ASP.NET 从 Gmail/Hotmail/Yahoo 导入通讯簿

使用 jQuery.ajax() 时如何处理错误?

在 asp.net 中调整图像大小而不会丢失图像质量

缩小失败.返回未缩小的内容

oAuth ASP.NET 成员资格提供程序

如何获得 System.Diagnostics.Process 的输出?

如何忽略身份框架的魔力,只使用 OWIN 身份验证中间件来获取我寻求的声明?

.NET 4.0 中的自定义 MembershipProvider

ASP.Net 无法创建/卷影复制

使用 Twitter Bootstrap 在 @html.actionlink 中显示 html

MVC3 和实体框架

字体真棒里面asp按钮

使用 jQuery 从 asp:RadioButtonList 读取选定的值