简体   繁体   English

如何在asp.net mvc身份上设置自定义身份验证?

[英]How to setup a custom authentication on asp.net mvc identity?

What I Need?! 我需要的?! I have an ASP.NET identity system setup and running with external logins. 我有一个ASP.NET身份系统设置并运行外部登录。 For whatever reason i need to setup a custom authentication after the ASP.NET identity authentication. 无论出于何种原因,我需要在ASP.NET身份验证后设置自定义身份验证。 Let me explain how? 我来解释一下怎么样? Lets say I have three pages for the users to view on my application, Page A,B,C. 假设我有三个页面供用户查看我的应用程序,页面A,B,C。 Who can view Page A? 谁可以查看Page A? Any anonymous user can view page A. Who can view Page A & B? 任何匿名用户都可以查看页面A. 谁可以查看页面A和B? Any user who have created an account either with his/her email & password or with external logins. 任何使用他/她的电子邮件和密码或外部登录创建帐户的用户。 Who can view Page A,B & C? 谁可以查看Page A,B&C?

Here is the place i want to set custom authentication. 这是我想要设置自定义身份验证的地方。 Any user who have created an account either with his/her email account or external logins AND has a valid serial key. 任何使用其电子邮件帐户或外部登录名创建帐户并且具有有效序列密钥的用户。 Serial Key? 序列号? I set a class in ASP.NET identity as below: 我在ASP.NET身份中设置了一个类,如下所示:

 public class UserDetails : IdentityUser
    {
        public virtual MembershipSerial MembershipSerial { get; set; }
    }

    public class MembershipSerial
    {
        [HiddenInput(DisplayValue=false)]
        public int Id { get; set; }
        [HiddenInput(DisplayValue=false)]
        public string Serial { get; set; }
        [Required]
        [Display(Name="Membership Serial")]
        public string SerialConfirmed { get; set; }
    }

    public class MyDbContext : IdentityDbContext<UserDetails>
    {
        public MyDbContext()
            : base ("EFDbContext")
        {
        }
        public System.Data.Entity.DbSet<MembershipSerial> MembershipSerial { get; set; }
    }

As you see above class i set up three properties in the class. 如上所述,我在课堂上设置了三个属性。 Field Id is for the Ids of the serials, The Serial is a 14 Alpha numeric letters which is entered by the administrator and as you can see it is a hidden field which not allowing null. 字段ID用于序列号的ID,序列号是14个字母数字字母,由管理员输入,您可以看到它是一个不允许为空的隐藏字段。 The field SerialConfirmed is also a 14 Alpha Numeric letters which will be entered by the users to authenticate in order to do some certain tasks in the application. 字段SerialConfirmed也是一个14字母数字字母,用户将输入这些字母进行身份验证,以便在应用程序中执行某些特定任务。 The whole concept is, that a logged in user should be pushed for a second type authentication which is authentication vs serial numbers. 整个概念是,应该推送登录用户进行第二种类型的身份验证,即身份验证与序列号。

I am seriously in need of help and searching online didn't help too much. 我非常需要帮助,在网上搜索并没有太多帮助。 If you need more information or yet its is unclear don't hesitate to ask me. 如果您需要更多信息或尚不清楚,请不要犹豫,问我。 Regards Edit: I am using EF code first. 问候编辑:我先使用EF代码。 Dostdar Dostdar

It seems like a custom authorization attribute would work. 似乎自定义授权属性可行。 Here's an example implementation: 这是一个示例实现:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class RequiresSerialValidationAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        bool hasValidSerial = false;
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            string userName = filterContext.HttpContext.User.Identity.Name;

            if (!string.IsNullOrWhiteSpace(userName))
            {       
                string serial = string.Empty;// TODO: Retrieve user's previously authenticated serial, perhaps from Session or a cookie?

                if(!string.IsNullOrWhiteSpace(serial))
                {
                    var service = DependencyResolver.Current.GetService<IYourAuthService>();
                    hasValidSerial = service.IsSerialValidForUser(userName, serial);
                }
            }
        }

        if (!hasValidSerial)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "yourserialauthcontroller", action = "yourauthaction", area = string.Empty }));
        }
        else
        {
            base.OnAuthorization(filterContext);
        }
    }
}

You would decorate the action methods with this attribute: 您可以使用此属性修饰操作方法:

[RequireSerialValidation]
public ActionResult SomeAction()
{
}

The attribute would trigger a redirect to your challenge action, where you prompt your user for their serial. 该属性将触发重定向到您的质询操作,您可以在其中提示用户输入序列号。 Assuming all goes well, you store their serial somewhere (Session could work here, or create an encrypted cookie), and then redirect back to the original action. 假设一切顺利,您将其序列存储在某处(Session可以在此处工作,或创建加密的cookie),然后重定向回原始操作。 On this second attempt, you've already verified that the action is allowed, so no redirect occurs. 在第二次尝试时,您已经验证了该操作是否被允许,因此不会发生重定向。

Your authentication service can be whatever you want it to be. 您的身份验证服务可以是您想要的任何服务。 In this example, I assume you're using dependency injection and that you've configured the global dependency resolver. 在此示例中,我假设您正在使用依赖项注入,并且您已配置了全局依赖项解析程序。 Given that, your IYourAuthService could look like this (omitting other methods): 鉴于此,您的IYourAuthService可能如下所示(省略其他方法):

public IYourAuthService
{
    bool IsSerialValidForUser(string userName, string serial);
}

with an implementation like so: 像这样的实现:

public YourAuthService : IYourAuthService
{
    public bool IsSerialValidForUser(string userName, string serial)
    {
        using(var context = new YourEntityFrameworkDbContext())
        {
            return context.Users.Any(u => u.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) && u.Serial.Equals(serial, StringComparison.OrdinalIgnoreCase));
        }
    }
}

This assumes you have a table called User (or Users ) in your database, and that UserName and Serial are fields on that table. 假设您的数据库中有一个名为User (或Users )的表, UserNameSerial是该表上的字段。 StringComparison.OrdinalIgnoreCase lets you do a case-insensitive, culture-insensitive match on the strings you're attempting to compare. StringComparison.OrdinalIgnoreCase允许您对要尝试比较的字符串执行不区分大小写,不区分大小写的匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM