How to authenticate certificates instead of passwords?

I have a small C # MVC5 application that I am creating and am ready to add a user security module to it. (I previously just created a session variable for testing roles). However, my security needs do not fit into any of the pre-prepared security modules that I saw, i.e. SimpleMembership etc.

Here is a summary of my situation and needs:

  • No passwords - username / password not allowed

  • Users authenticate at the web server level using a smart card with a client certificate - I do not manage the server and will never see their card.

  • IIS fills out Request.ClientCertificate and several others, that's all I have to access

  • My application will have dedicated user accounts - without using Windows auth, etc. - therefore it looks more like a username and password system without entering a username or password

  • The server authenticates them to access the server using some form of Windows authentication with a smart card certificate, but I canโ€™t, I just have to accept the certificate uploaded to the request collection

  • User tables are stored in SQL Server (currently ...)

  • Prefer not to use EntityFramework, since all application data comes from the Oracle database and tries to get permission to transfer authentication / authorization tables to it and exclude work from two databases, and EF for Oracle does not work in our environment, so instead I use OleDb: (

What is the best way to implement such a scheme? What I started to do was create three tables - "Users, roles" and "UserRoles", and the "Users" table contains a copy of the (string) ClientCertificate. Users entering the system will be authenticated in the application, pulling out Request.ClientCertificate and looking for a suitable user record, and then getting the list of roles from UserRoles. The user object will be stored in a session containing user information and roles, and the attributes will be used on the controllers to control access, requiring specific roles.

(we have another application that uses this basic approach, but it is J2EE on Linux, so I cannot just reuse its code)

However, I also started reading about IIdentity and IPrincipal, but I'm not 100% clear if this is really what I can use. Obviously, I would prefer to use a security model developed by experts. So should I create my authentication system using custom classes that inherit from IIdentity and IPrincipal? Or is there some other approach I should use?

It is possible that something like SimpleMembership can be customized to meet my needs, but if so, I donโ€™t know about it.

Thanks for the advice, very grateful.

+7
authentication c # asp.net-mvc
source share
2 answers

You can use Microsoft Identity for this kind of advanced scenario. The identity is so modular that you can use any data warehouse with any necessary scheme. Identity authentication password is not needed, you can implement your own script. 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 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 the user and filled roles without any dependence on the username, password and any data store, since we used our own user manager.

Usage example:

 [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 } 

This is a simple example of how you can implement your own advanced IIdenity script. Read my other similar answers, for example, and for more examples to see how you can do almost everything: Claims .

You can also view and download the Token Based Authentication Example as a simple working example.

+5
source share

The user is already authenticated from the sounds of this user, so in your controller you can simply access the User property in the base class Controller , which inherits your controllers. This property returns a IIPrincipal , which has an Identity property that returns IIdentity .

So, for example, if you want to get the name of the user currently registered in your controller, you will get access to User.Identity.Name or if you want to make sure that the user is registered, you can check User.Identity.IsAuthenticated .

You absolutely should not pull any of the client certificates, in fact, the server had to go through user authentication, you do not care that this was done through a certificate, not a username / password.

0
source share

All Articles