如何使用证书代替密码验证? [英] How to authenticate with certificates instead of passwords?

查看:222
本文介绍了如何使用证书代替密码验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我建立一个小的C#应用​​程序MVC5和我准备给用户安全模块添加到它。 (previously我刚刚创建一个会话变量用于测试的角色),但我的安全需求不适合任何我见过的prebuilt安全模块,即的等SimpleMembership

I have a small C# MVC5 app that I'm building and am ready to add the user security module to it. (previously I just created a session variable for testing roles) However, my security needs do not fit any of the prebuilt security modules that I've seen, i.e. SimpleMembership etc.

下面是我的情况的总结和需要:

Here's a summary of my situation and needs:


  • 没有密码 - 用户名/密码身份验证是的的允许

用户使用带有客户端证书的智能卡在网络服务器级别的认证 - 我不管理的服务器,绝不会看到自己的卡

Users are authenticated at the web server level using a smartcard with client certificate -- I do not manage the server and will never see their card

IIS填充Request.ClientCertificate和其他几个人,这是我有机会获得

IIS populates the Request.ClientCertificate and a few others, this is all I have access to

我的应用程序将拥有专门的用户帐户 - 不使用Windows身份验证等 - 因此更像是一个用户名/密码系统,而没有输入用户名或密码

My app will have dedicated user accounts -- not using Windows auth etc -- so more like a username/password system without ever entering a username or password

服务器的验证是他们访问的服务器的使用某种形式的Windows验证其智能卡证书的,但我不能,我只是不得不接受装入Request集合证书

The server is authenticating them to access the server by using some form of Windows auth with their smart card certificate, but I can't, I just have to accept the certificate loaded into the Request collection

用户表存储在SQL Server(现在...)

User tables are stored in SQL Server (for now...)

preFER不使用的EntityFramework,因为所有的应用程序的数据来自于Oracle数据库,并试图获得批准移动认证/授权表到它,并消除来自两个区议会的工作,和EF甲骨文没有按'在我们的环境将不起作用,所以我使用的OleDb代替:(

Prefer not to use EntityFramework, since all app data comes from an Oracle DB and trying to get approval to move authentication/authorization tables into it and eliminate working from two DBs, and EF for Oracle doesn't work in our environment, so I'm using OleDb instead :(

什么是去实施这样一个计划的最佳方式?我已经开始做的是建立三个表 - 用户,角色和的UserRole - 以及用户表保存(串)ClientCertificate的副本。谁在用户将拉动Request.ClientCertificate,寻找匹配的用户记录,然后让角色从在的UserRole名单进行身份验证到应用程序。用户对象将被存储在包含用户和角色信息的会话和属性将在控制器一起使用,要求某些角色来控制访问。

What is the best way to go about implementing a scheme like this? What I've started doing is building three tables -- Users, Roles, and UserRoles -- and the Users table holds a copy of the (string) ClientCertificate. Users who come in would be authenticated into the app by pulling the Request.ClientCertificate and looking for a matching Users record, then getting the list of roles from UserRoles. A user object would be stored in the session containing the user and role info, and attributes would be used on controllers to control access by requiring certain roles.

(我们使用这个基本方法的另一个应用程序,但它是在Linux上J2EE,所以我不能只重用其code)

(we have another app that uses this basic approach, but it is J2EE on Linux so I can't just reuse its code)

不过,我也开始阅读有关的IIdentity和IPrincipal的,但我不是不论这是否是我可以用清晰的100%。显然,我想preFER使用由专家设计了一个安全模型。所以,我应该建立使用来自的IIdentity和IPrincipal的继承自定义类,我的身份认证系统?或者是有一些其他的方法,我应该使用?

However, I've also started reading about IIdentity and IPrincipal but I'm not 100% clear on whether or not that is something I can use. Clearly I'd prefer to use a security model designed by experts. So should I build my authentication system using custom classes that inherit from IIdentity and IPrincipal? Or is there some other approach I should use?

这是完全可能的,像SimpleMembership可定制,以满足我的需求,但即便如此,我没有意识到这一点。

It is entirely possible that something like SimpleMembership can be customized to meet my needs, but if so I'm not aware of it.

谢谢你的建议,很多AP preciated。

Thanks for the advice, much appreciated.

推荐答案

您可以使用微软的身份为这种先进的方案为好。 Identity,以便模块化你可以使用任何数据存储你想要的任何方案。密码的身份认证是没有必要的,你可以实现自己的场景。考虑这个简单的例子:

You could use Microsoft's Identity for this kind of advanced scenarios as well. Identity so modular you could use any data storage with any schema you want. Password for authentication in Identity is not necessary you could implement your own scenario. consider this simple example:

// imaging this action is called after user authorized by remote server
public ActionResoult Login()
{
    // imaging this method gets authorized certificate string 
    // from Request.ClientCertificate or even a remote server
    var userCer=_certificateManager.GetCertificateString();

    // you have own user manager which returns user by certificate string
    var user=_myUserManager.GetUserByCertificate(userCer);

    if(user!=null)         
    {
        // user is valid, going to authenticate user for my App
        var ident = new ClaimsIdentity(
            new[] 
            {
                // since userCer is unique for each user we could easily
                // use it as a claim. If not use user table ID 
                new Claim("Certificate", userCer),

                // adding following 2 claim just for supporting default antiforgery provider
                new Claim(ClaimTypes.NameIdentifier, userCer),
                new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),

                // an optional claim you could omit this 
                new Claim(ClaimTypes.Name, user.Name),

                // populate assigned user's role form your DB 
                // and add each one as a claim  
                new Claim(ClaimTypes.Role, user.Roles[0].Name),
                new Claim(ClaimTypes.Role, user.Roles[1].Name),
                // and so on
            },
            DefaultAuthenticationTypes.ApplicationCookie);

        // Identity is sign in user based on claim don't matter 
        // how you generated it Identity take care of it
        HttpContext.GetOwinContext().Authentication.SignIn(
            new AuthenticationProperties { IsPersistent = false }, ident);

        // auth is succeed, without needing any password just claim based 
        return RedirectToAction("MyAction"); 
    }
    // invalid certificate  
    ModelState.AddModelError("", "We could not authorize you :(");
    return View();
}

正如你可以看到我们的授权用户和角色的人口没有任何依赖于用户名,密码,因为我们用我们自己的用户管理的数据存储。

As you can see we authorized user and populated roles without any dependency to username, password and any data storage since we used our own user manager.

一些用法示例:

[Authorize]
public ActionResult Foo()
{
}

// since we injected user roles to Identity we could do this as well
[Authorize(Roles="admin")]
public ActionResult Foo()
{
    // since we injected our authentication mechanism to Identity pipeline 
    // we have access current user principal by calling also
    // HttpContext.User
}

这是可以实现自定义的情况下延长 IIdenity ,以及一个简单的例子。像读<我的一个其他类似的答案href=\"http://stackoverflow.com/questions/29988858/custom-authentication-and-authorization-based-on-user-rights/31755231#31755231\">this和<一个href=\"http://stackoverflow.com/questions/31846452/claim-based-authorization-design-for-conditional-edit-operation-in-asp-net-mvc-a/31851128#31851128\">this更多的例子来看看如何通过声明

This is a simple example you could implement your custom scenario extend IIdenity as well. Read my other similar answers like this and this for more examples to see how you can do almost everything by Claims.

此外,你可以浏览和下载基于令牌身份验证示例回购作为一个简单的工作示例。

Also you could browse and download Token Based Authentication Sample repo as a simple working example.

这篇关于如何使用证书代替密码验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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