Simple way to authenticate users in ASP.NET MVC without providers - asp.net-mvc

I'm trying to understand how authentication in ASP.NET MVC works. I do not want the built-in MembershipProvider creating a local database behind the scenes. I've also looked at some blog posts talking about custom membership providers. While looking for a much simpler forms authentication model, I found the following:
FormsAuthentication.SetAuthCookie("myusername", true);
FormsAuthentication.SignOut();
The idea is to send the username and salted hashed password to the database and see if they match a record in there. If the user exists, then I pass the username to SethAuthCookie. My questions are:
Should the username be encrypted?
What happens if there are multiple servers and the user is surfing the website? I believe any one of the servers can serve content to the user, so how do they know if the user has been authenticated?
What's the preferred way of authenticating users in MVC without providers? Am I on the right track or should I be looking into something else?

Should the username be encrypted?
No.
What happens if there are multiple servers and the user is surfing the
website? I believe any one of the servers can serve content to the
user, so how do they know if the user has been authenticated?
At each request the server reads the authentication cookie that is sent by the client browser and which was generated by the FormsAuthentication.SetAuthCookie call, decrypts it and retrieves the username that is stored inside. Just make sure that you have set the same machine keys for all nodes of your server farm so that no matter which node emitted the authentication cookie, all other nodes can decrypt it.
What's the preferred way of authenticating users in MVC without
providers? Am I on the right track or should I be looking into
something else?
You are on the right track. You use the FormsAuthentication.SetAuthCookie method to emit the authentication cookie once you have verified that the password hash matches the one of the user in the database and in subsequent actions you could use the User.Identity.Name property to retrieve the currently authenticated user.
I would also recommend you checking out the following article which provides a good overview of how forms authentication works in ASP.NET.

Related

How to authenticate based on devise encrypted password?

I have two Rails apps using devise for authentication: a website and an API. Even though I'm the owner of these 2 apps, for many reasons, I wanted complete separation between the two. When a user signs up on the website, an account is automatically created on the API side. The biggest problem I have is keeping the users table in sync between the two apps. I ended up with a bunch of RESTful API callbacks on the website user model which create/update the API user.
The second part is calling the API on behalf of the user logged into the website. Problem is that I don't have the user's decrypted password so I can make the API call. All API calls use basic HTTP authentication. The passwords are hashed into the database and cannot be decrypted (which is a good thing, thank you devise). Because I keep all users columns in sync between the 2 databases, my website users encrypted_password column is identical to my API users encrypted_password column.
So, what options do I have for solving this? I'm thinking either modifying the API such that an admin call for each regular call takes an admin username and password and a user ID (to get that user's transactions for example). Or, implement a shared database between the 2 apps - but I have a lot of associations between users and other models... how would indexing even work?! Or, hijack the devise authentication and compare encrypted_password (from my website) to encrypted_password (to my API) - since they are the exact same; but this opens a security can of worms. Or, create keys authentication and generate unique GUIDs for users... but then that would be just as bad as having decrypted password stored in a database. I hate all these solutions. Perhaps someone has a better idea?
When you authenticate a user in Devise it takes the plaintext password and combines it with a pepper and passes it through bcrypt. If the encypted password matches the value in the DB the record is returned.
The pepper is based on your rails app secret. So unless the two apps have the exact same secret then authentication will fail even if you have the correct encrypted password. Remember that the input to bcrypt has to be identical to give the same result. That means the same plaintext, salt, pepper and number of stretches.
You're correct in that sharing the passwords back and forth is not a solid solution. You are also correct in that using UUIDs instead of a numerical auto-incrementing id is part of the solution.
What you can do is implement your own authentication provider. The Doorkeeper gem makes it pretty easy to setup your own OAuth provider (or you can use Auth0 if using an external service is acceptable).
The web app would use Devise + OmniAuth to authenticate users against the authentication provider and use the credentials returned to identify the user in the web application.
For the API application I would use Knock for JWT authentication. Where the API server proxies to your authentication server via the oauth gem.
However you should consider at this point if your web and API app really should be running on separate DBs. Keeping writes in sync across both DBs can be quite the task and your should ask yourself if your really need it at this stage.
JWTs would make it easy to include information such as user id right in the JWT without relying on external persistence such as a users table. Just ensure the token is correctly signed and don't store personal information in it such as email since usually JWTs are not encrypted but only signed.
I actually did a write up tutorial on this while back if interested.
https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/

MVC4 Simple Membership authentication with multiple databases or providers

I'm working on an MVC4 site using SimpleMembership to handle user accounts and role based authentication. We have another site and we'd like to implement a single sign on system allowing users from the existing site to log in to the one I am building. What would be the best way to achieve this and hopefully leverage to the existing roles based authorization I'm using on the MVC4 site. Is it possible to have multiple membership providers (i.e. use the built in one and if the user is not found, attempt to authenticate via a custom provider that I'll write (once I work out how!). Or would it be better to abandon the built in membership/roles and roll my own?
I also thought of letting WebSecurity check the local database and if the user is not found, query the 2nd database and if the users credentials are valid, create a local account for them. One issue with this approach is if a user called Fred registers on the MVC site, and then a user from the other site called Fred logs in, we couldn't create them a local account with the same username. We could prefix/suffix the username with some text to indicate that they are from the other site but then we lose the single sign on feature.
We will also want to integrate AD authentication for staff in the future.
So essentially I'm looking for the best way to authenticate users from multiple databases and keep using roles based authentication?
I've also done a little digging was wondering if ADFS might be useful for this.
Any help or advice would be greatly appreciated!
I recommend the use of an Identity server to handle all your login request and switching to a claim based authentication instead of a role based authentication if you can.
I personally went with Thinktecture IdentityServer
pluralsight.com have a good course on it.
Thinktecture IdentityServer is build on top of simple Membership and it supports multiple protocol such as
WS-Federation
WS-Trust
OpenID Connect
OAuth2
ADFS Integration
Simple HTTP
I recommend checking it
Good Luck

Most secured way to persist data in ASP MVC

I'm using ASP MVC application + WCF service with custom session behavior implementation. Clients receive, store and use (for authorization) session tokens. Now I'm searching for most secured way to store session token at client side in ASP MVC.
I see few ways:
Hidden field. Drawback: user can open page source code and get token.
Route value. Drawback: token is actually open. User can get it from address bar.
Session. I've read a lot articles with one conclusion: using Session in MVC application is a bad practice. But Session have a lot advantages as well: can be widely
configured, can store token at server side, etc.
I'm sure there are some best practices for solving my problem. Any help will be appreciated.
Require HTTPS connections, encrypt secure data, place in cookie.
You could also pass the token around your site, encrypted of course via a hidden field or something but your scenario is actually what cookies are made to do.
My bank sets a cookie, they should be good enough for what you are doing.

How do I implement custom role authorization with ADFS in ASP.Net MVC2?

I'm pretty new with ADFS and and Custom Role authorization so any help (and a lot of patience) would be greatly appreciated.
I'm trying to set up ADFS with custom authorization. I have the ADFS set up to return me a claim, from there I can get a username from the name token. However, I already have an existing roles table which I need to map up to the username from the token and set the session object to reflect his roles?
I guess what I'm very confused about (besides what seems like everything right now) is when the claim comes back, what controller is hit to process the token?
Before changing my app to use ADFS authentication, it would:
1) hit the AccountController,
2)validate the user, and
3)set the Asp.net session to store the users info.
Now that I'm using ADFS, it seems to authenticate the user, and then populate the session without me knowing where to intercept and put in custom roles code?
Can someone offer some direction?
What you need to do is send across all AD groups in some ADFS rule, and then convert those roles to groups in another rule. Let me know if you want more details instructions.

asp.net mvc storing username / other ID information after forms authentication for communicating with stateless wcf services

I have reviewed some of the similar questions on this site but could not find one with an answer appropriate for my situation.
I am using asp.net mvc, and it is communicating securely with stateless wcf services. for each service call, i need to pass in the username and a few other ints for identification purposes. - not password, the services are not authenticating.
I am using forms auth to authenticate the users. I am just not sure where, after the user logs in, I should store their username and other account details used for the scope of the user's time logged into the site. suggestions for webforms apps include in "Session". Is there an equivilent alternative in MVC? is storing the info in the forms auth cookie the best solution? it seems like it would be slow to have that info in a cookie as opposed to somewhere else in memory..
thanks
If you need access to a select few bits of information about the current user over and over again, you could combine FormsAuthentication with a custom principal implementation.
The Forms authentication mechanism will write a cookie to your client's disk, and will recreate the custom principal based on that cookie for each call. You could e.g. store something like a user "level", a user "profile" or other small chunks of information, which would then be accessible through the HttpContext.Current.User at any time during the lifetime of your request.
Check out these resources on the topic:
MSDN docs on How to Create a Custom Principal Identity
Using Custom Principal with Forms Authentication in ASP.NET
and I'm sure googling or binging for "ASP.NET custom principal" will render quite a few more hits for you!
yes, unless it's a lot of information, the preferred location is to store it in the cookie. Aside from that, session is the next best place.

Resources