MVC3 Loosly coupled authentication - asp.net-mvc-3

Out of the box MVC3 applications allow Windows Authentication when using the Intranet project template, or the Forms Authentication for an Internet project template. I've got a site that I'd like to use either. In addition, I've got an existing site that uses it's own custom type of authentication that authenticates users (no authorization or roles, just identification). I may need to use functionality of each, in addition to the data from the legacy system for authentication. Due to this, I'm trying to determine a way to abstract my authentication and decouple it. I'd like to use some kind of dependency injection, based entirely upon configuration, so I could deploy this same site in two different locations, and switch the authentication model (Windows Auth/Forms Auth/ Custom Auth), by changing configuration only.
Currently, all the ASP.NET applications I've worked with, including the MVC3 template projects, seem to be very tightly coupled with the authentication type used.
Am I thinking too far outside of the box on this one?
Is this possible, or is there a reason for this tight coupling?
UPDATE
The real problem I have is between the existing legacy authentication I need to use for some users, versus the Forms Authentication I need for others.
The Windows versus Forms authentication isn't really a problem, due to the LogIn form not being used for one. But consider the Custom Authentication and Forms Authenication. The LogIn form is tightly coupled to FormsAuthentication, more specifically to System.Web.Security. (i.e. Membership.ValidateUser, FormsAuthentication.SetAuthCookie, etc...).
I'd like to Inject into my AccountController the authentication to use, rather than having FormsAuthentication and Membership be used.
Does this make more sense in so far a what my problem is?

They're actually not so tightly coupled. The templates are just trying to get you up and running quickly.
ASP.NET membership supports both Forms and Domain auth.
In a site configured for Forms auth, e.g., you'll see a line in Web.config like:
<authentication mode="Forms">
You can change that to:
<authentication mode="Windows">
That's not the only difference (with Windows auth, e.g., you don't need a login page), but it's the most significant. You write your code based on the ASP.NET Membership API and only target Forms authentication in particular when you have to.

I agree with Craig's answer. The only thing I have to add is that I consider just about anything you can change in the web.config to be loosely coupled. The reason is that you can apply web.config transforms when you create a deployment package for your MVC app.
We use Unity for DI/IoC, and you can also specify your injection dependencies in web.config using Unity. You would just write your Web.Auth1.config to configure your app for one kind of authentication, and Web.Auth2.config to configure it for another kind of authentication. Then when you deploy, you just pick the target and VS builds the correct configuration for you.
If your source code needs to know which type of auth is used in the deployment, you could tell it with a web.config appSetting, which can also be changed with a web.config transform during deployment.

Related

Combining Azure AD (b2c) custom ClaimsIdentity

I have an ASP.NET 5 (RC1) application for which I am trying to set up authentication and authorization. However I am confused and overwhelmed by all the varying authentication and authorization information online in as it pertains to this platform. Much of it seems either hopelessly out of date or simply doesn't seem to apply in this particular usage scenario. Right now, I'm not even sure what the right 'terminology' to use for the question I am trying to ask, but I digress.
What I am trying to accomplish is a system whereby users are authenticated/authorized via Azure AD (B2C?), with additional user profile information stored in a database. However, the user context in the controllers is accessed in a consistent way using what I presume would be a custom ClaimsPrincipal/ClaimsIdentity? I would imagine this should be as simple as adding an 'authorize' attribute or something similar and accessing the ClaimsPrinciple.Current.Claims.
I have used ASP.NET Identity in the past, but many of the examples I have found aren't using that. Most are simply using the UseOpenIdConnectAuthentication middle-ware. I see that ASP.NET Identity is still available but I'm not sure it applies in this scenario. I also found a couple posts on here suggesting using a custom ClaimsIdentity to accomplish this, but I am having trouble finding useful up to date examples. BTW, I realize that much of this "profile" information can be stored as custom attributes in azure ad but the way some of the information is used within the application prohibits all of it from being in azure (i.e. EF linq joins and such).
Please, tell me if I am even close on some of this. I know this is a fairly new platform and the information is sparse, but certainly I'm not the only one asking these questions.
Just calling out an excellent article Identity management for multitenant applications in Microsoft Azure.
A lot of your questions are answered there.
e.g. you can augment the claim in the OWIN middleware AuthenticationValidated event.
ASP.NET Identity is claims-based in that the attributes are delivered as claims but authentication is on the DB, not via external IDP like Azure AD.
B2C is a special case in Azure AD - used for many (millions!) external users who can self-register and self-manage e.g. SSPR.
B2C uses a separate tenant to the normal Azure AD one and the users have no access to things like O365 or any SaaS applications.

MVC - Forms and Windows authentication

I'm hoping this is possible. Note that I'm NOT trying to mix the two authentication forms. My goal is to have an existing site secured as it is now with Forms authentication. I don't want Windows authentication to work in any existing pages, we use Authorize attributes to secure controllers and that should continue to function as is.
I'd like to add an MVC Area where ONLY Windows authentication will work. I was thinking of creating a new Authorize attribute subclass that will only accept Windows integrated authentication, but I'm not sure how to specify which authentication mode for the site vs. the area.
How would I configure such an application?
Since MVC doesn't use the physical folder structure (except for Content, like scripts, images, css, etc.. and even then in MVC4 much of that is now virtualized in bundles), all authentication is done at the root of the site, more or less.
You would be better off creating a sub-site with it's own web.config and authentication settings rather than trying to do two forms of authentication in the same site.

Implement Web API with OAuth and a Single Page Application

We're developing an API and a single page application (that is one of more possible future consumers of it).
We already started on the web API, and basically implemented a system very similar to the one John Papa made in his course on pluralsight, named "Building Single Page Apps (SPA) with HTML5, ASP.NET Web API, Knockout and jQuery".
We now need to implement authentication and user managing in this application and need to find the easy way out to implement this in as little time as possible as we are in a hurry.
We realized the SPA template included in the ASP.NET update had very similar features to our needs, but we wonder what the best approach to implement a similar feature in our existing code.
We are novice developers, as you might figure.
Is it possible nstall some packages using the package manager, and voila, a simple membership and OAuth auth option be readily available?
Our use case is that we need to protect some resources on our API based on roles, and that one should be able to log in using a username and password, but also log in using ones facebook, google, or twitter account.
Found an interesting talk regarding the subject here: https://vimeo.com/43603474 named Dominick Baier - Securing ASP.NET Web APIs.
Synopsis: Microsoft’s new framework for writing RESTful web services and web APIs is appropriately enough called ASP.NET Web API. As the name applies, this technology is part of ASP.NET and also inherits its well-known security architecture. But in addition it also supports a number of new extensibility points and a flexible hosting infrastructure outside of IIS. There are a number of ways how to do authentication and authorization in Web API - from Windows to usernames and passwords up to token based authentication and everything in between. This talk explores the various options, and puts special focus on technologies like claims, SAML, OAuth2, Simple Web Tokens and delegation.
We eventually went with the SPA template, doing authentication on the API (separate MVC part).
Then the API would generate a unique token and redirect the user to the front-end with the token in url parameters.
The front-end then needs to send this token on every subsequent request.
Have a look here - Identity Server done by the security experts. This is all you need in one package.
In terms of OAuth, you would need to use Client-Side Web Application flow which the access token is issue immediately to the client and can be used.

MVC3 app using asp.net membership /claims aware application + STS

I have this in mind.
I just want to check if there is something like what I have in mind already done, or I should I want to work on:
MVC3 application using asp.net membership, that has single sign on (so it is a claims aware
app that will log on a STS).
I have seen http://identityserver.codeplex.com/ but not analized it in detail:
Is it a good solution to implement?
My question is:
Is there anything like that done?
Is it a common way of doing SSO? (using also membership?)
Thanks!..
IdentityServer is an STS not an application.
If you have a claims-aware application, it "emulates" the membership provider. You can configure ADFS to provide the roles and then use the standard .NET constructs
IsInRole() or
location>
...
allow role = ...>
in the web.config.

ASP.NET MVC3: Do I need to use a MembershipProvider?

I am building a multi-tenant site with MVC3. Prior to this project I had never touched either the .NET stack or web development in general, so as you can imagine my domain knowledge is somewhat lacking.
I'm still using the default AccountController architecture, but I pretty quickly determined that I didn't want to use aspnetdb.mdf for authentication, as its design is pretty different from my requirements. I do want role-based authentication, so I ultimately wrote custom User and Role classes as code-first Entity classes and used this tutorial to set up a custom MembershipProvider and RoleProvider.
Everything works fine at the moment, but as I'm building the multi-tenancy functionality it's getting messier. Based on this example, I am using a custom extension of Controller which keeps track of which tenant is using this session, and all my controllers extend this class instead of the base Controller class.
All tenants are using the same database. Each entity has a Tenant property that identifies who it belongs to.
So, here's the problem:
Usernames do not need to be globally unique. Only the combination of username and tenant must be unique. Thus, ValidateUser needs to know the username, password, and tenant. Since my custom MembershipProvider is not a Controller, it doesn't know which tenant is using the session, and the ValidateUser method only accepts username and password so I can't pass it that information.
Furthermore, pretty much everything MembershipProvider does besides ValidateUser is already implemented in a UserRepository class, which that tutorial told me to make. I'm rather fond of the Repository pattern, and it's way more convenient than adhering to MembershipProvider's interface, but now there's a massive conflict of interest between UserRepository and MembershipProvider.
So, my question:
Do I need to use MembershipProvider, or even Membership, at all?
It seems like everything MembershipProvider does would be performed more conveniently by my repository class. At this point all I'd have to do is write a new Authorize attribute that doesn't rely on Membership, and everything should work without any MembershipProvider at all, right? If I don't drop Membership I'm forced to completely mutilate my MembershipProvider implementation to the point that it barely resembles the original interface anyway.
...Either that or Membership does a ton of things I'm unaware of and removing it is blatant stupidity. That is also a distinct possibility.
No, you don't need to use Membership, but consider for a moment exactly what Membership is. Membership does not involve your users names, or addresses, or other information. Membership is strictly related to the login account of the system. It only handles details with creating, validating, updating, or deleting the information needed to login. That's it.
Likewise, the Role system is only assigning a role name to the user.
Ultimately, Membership and Roles are just implementations of the IPrincipal interface. While FormsAuthentication is an implementation of the IIdentity interface. These work together so that you can utlize the built-in ASP.NET Authorization and Authentication system.
Membership actually does have the concept of multiple tennants. This functionality is accomplished via the "ApplicationNane" field of the aspnet_users table (also settable in the Membership class itself)
From the documentation on the Membership class:
The ApplicationName is used to identify users specific to an application. That is, the same user name can exist in the database for multiple ASP.NET applications that specify a different ApplicationName. This enables multiple applications to use the same database to store user information without running into duplicate user name conflicts. Alternatively, multiple ASP.NET applications can use the same user database by specifying the same ApplicationName. The ApplicationName can be set programmatically or declaratively in the configuration for the Web application.
Now, this is designed to typically be set in the Web.Config and stay the same for the life of the app, but I see no reason why you can't use it to specify which tennant you want.
The only issue here is that Membership.ApplicationName is static, which means it's shared by all threads running in the App Pool. However, if you use some kind of lock around accessing it, then this shouldn't be a huge issue (though it could affect scalability at some level).
This would basically allow you to use the standard, out of the box membership provider without any changes. You just have ot make sure to guard the access calls.
You don't have to use the membership provider at all. Its simply provided as a quick and consistent way to get up and running. Some choose it because it supports multiple databases (universal membership providers include azure as well as sql ce, express, and full) but for others trying to map it to your applications rules can be more difficult than the <5 lines of code it takes to authenticate and issue your own forms auth ticket.
With that said I'm assuming you are using forms authentication. You can simply issue the ticket yourself. I would still program against an interface for this which the default MVC template should have, so simply add in a new tenant id.
With that said, I'd consider having unique names. It ensures you don't 'forget' to do an additional tenant check somewhere else in the app and tenant1\userBip and tenant2\userBip surprisingly end up stomping on each others record at some point.
True, testing should uncover this - if testing is complete : )

Resources