如何为 ASP.NET MVC 2 创建自定义成员资格提供程序? [英] How do I create a custom membership provider for ASP.NET MVC 2?

查看:25
本文介绍了如何为 ASP.NET MVC 2 创建自定义成员资格提供程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何基于 ASP.NET 成员资格提供程序为 ASP.NET MVC 2 创建自定义成员资格?

How do I create a custom membership for ASP.NET MVC 2 based on the ASP.NET membership provider?

推荐答案

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

I have created a new project containing a custom membership provider and overrode the ValidateUser method from the MembershipProvider abstract class:

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);
    }
}

然后我通过添加一个引用并从我的 web.config 中指出来将该提供程序连接到我的 ASP.NET MVC 2 项目:

Then I connected that provider to my ASP.NET MVC 2 project by adding a reference and pointing it out from my web.config:

<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 方法.ASP.NET MVC 授权使用该方法找出分配给当前登录用户的角色,并确保允许用户访问控制器操作.

I do need to create a custom class that inherits the RoleProvider abstract class and overrides the GetRolesForUser method. The ASP.NET MVC Authorizing uses that method to find out which roles are assigned to the current logged-on user and makes sure the user is permitted to access the controller action.

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

Here are the steps we need to take:

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

1) Create a custom class that inherits the RoleProvider abstract class and overrides the GetRolesForUser method:

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 应用程序连接起来:

2) Connect the role provider with the ASP.NET MVC 2 application via our web.config:

<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"):

3) Set the Authorize(Roles="xxx,yyy") above the wanted Controller / Action:

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

就是这样!现在可以使用了!

That's it! Now it works!

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

4) Optional: set a custom Authorize attribute so we can redirect an unwanted role to an AccessDenied Page:

[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 属性来重定向我们的用户以访问被拒绝的视图:

Now we can use our own made attribute to redirect our users to access denied view:

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

就是这样!超级骗子!

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

Here are some of the links I've used to get all this info:

自定义角色提供者:http://davidhayden.com/blog/dave/archive/2007/10/17/CreateCustomRoleProviderASPNETRolePermissionsSecurity.aspx

希望这些信息有帮助!

这篇关于如何为 ASP.NET MVC 2 创建自定义成员资格提供程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆