ASP.NET MVC / Web API Custom Authentication

2019-06-24 02:49发布

I have ASP.NET MVC 4 / Web API hybrid application. The authentication is being handled by an existing application. In looking at securing these types of applications, most articles point to using Forms Authentication along with the [Authorize] attribute on the MVC and API controllers/actions you want to protect. I would like to use the [Authorize] attribute as it will handle both MVC routes and API routes but not sure how to do that without having an actual form and using the built-in membership provider.

Should I go with a simple approach like described here? Or should I create a Custom Membership provider that handles the logic?

For clarity, the workflow would be as follows:

  1. The user logs in through the existing authentication portal.
  2. If authenticated, they are redirected to my application along with some additional data like username and email (so no passwords need to be transferred)
  3. My application sets an authentication cookie that allows the user to continue using the application.

Any help would be greatly appreciated.

3条回答
Ridiculous、
2楼-- · 2019-06-24 03:13
  • Option 1

If your existing login portal is using Forms Authentication, then you can share the encryption keys between the applications so that they can read the authentication cookie created in the login portal:

How can I share .net (C#) based authenticated session between web forms and MVC2 applications?

  • Option 2

If you're not using forms authentication in the login portal, you could keep your existing process, but add on a step that manually creates the authentication cookie. There are lots of variations on this, but this question show a higher level way in the question, and a lower level method in the answers:

How can I manually create a authentication cookie instead of the default method?

This also requires the encryption configuration be the same between the applications.

  • Option 3

Otherwise you are either left with using an SSO protocol for the handoff. You can keep the existing authentication process for your login portal, but will need to add additional code to coordinate the SSO handoff to the other application. SSO came about because other than encrypted cookie methods used in #1 & 2 above, there is little other secure options for doing a browser redirect and communicating authentication.

Creating your own cookie based method is risky and may open up security holes that you don't foresee.

  • "Should I go with a simple approach like described here?"

The important thing about that example is it's not clear where username is coming from in SetAuthCookie(username, .... That question implies that the user will login to the additional application and that app will query the web service to determine if that login is valid. In this case it's not single sign on with a dedicated login portal, but instead each app collects login information and asks the web API if it is valid. In your case, you do not want to collect the login information in each portal, but instead detect that they've already logged in to the deicated login portal.

So the problem is how does the login protal tell you in a secure fashion what username is when you call SetAuthCookie(username, .... That's exactly what SSO is for. Using a SSO handoff, one site can tell the other in a secure fashion that "I'm sending Bob123 to you, and you can be sure it is really Bob123 and not someone else.

Options #1 and #2 get around this by having the login portal set the cookie instead, and by sharing keys across the apps, the other apps can securely read that cookie.

Note you can't do this with just any cookie. The forms authentication cookie is built in a certain way to prevent forgery of the cookie and other tampering.

SSO becomes your only option if you are going across domains because cookies written in one domain cannot be read in another(the browser only submits cookies for the current comain).

There are workarounds for forms authentication with multiple subdomains sharing a root domain:

Proper creation of a cross-domain forms authentication cookie

There are various hacks for redirecting to another site with encrypted information and letting that site write the forms authentication cookie, but most of them are just horrible hacks that are just as complicated as SSO.

查看更多
倾城 Initia
3楼-- · 2019-06-24 03:15

You can use Owin to handle this. Here's a code snippet I am using to authentication using Facebook, it also uses cookie:

using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;

namespace ASPNetMVC53rdPartyAuth
{
    public partial class Startup
    {

      public void ConfigureAuth(IAppBuilder app)
      {
        // Enable the application to use a cookie to store information for the signed    
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login")
        });
        // Use a cookie to temporarily store information about a user logging in with a              
        // third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // third party login providers: 


        // You have to register this app at https://developers.facebook.com/ and get the     
        //appId and appSecret.   
        // Facebook requires SSL, so that need to be enanbled.  Project url can be found  
        // under project properties and can be localhost.
         app.UseFacebookAuthentication(
           appId: "xxxxxxxxxxxxxxxx",
           appSecret: "xxxxxxxxxxxxxxxx");
         );           
      }
    }
}
查看更多
放荡不羁爱自由
4楼-- · 2019-06-24 03:26

You seem to try to reinvent a Single Sign-On protocol. Instead, there are existing SSO protocols like OAuth2 or WS-Federation you should definitely learn about.

In general, SSO protocols work similarily to what you expect your "workflow" to behave. The exact flow can differ but this is always the Identity Provider that authenticates/authrorizes users and the IdP somehow passes this information to the application that makes use of it (for example, the application issues a custom cookie to establish user authentication).

The Authorize attribute is not intended to be used with Forms Authentication only. Any authentication module that sets the principal for the request lifetime can replace Forms. For example, the Session Authentication Module is often used nowadays as it fixes some particular issues of the Forms module (e.g. the inability to persist long user data).

If you need a good free book on SSO, take a look here:

http://msdn.microsoft.com/en-us/library/ff423674.aspx

查看更多
登录 后发表回答