.NET Authentication framework equivalent to Devise for Ruby - c#

I'm making an app in Xamarin that requires login using local user accounts (not using any third party OAuth such as Google or Facebook) and I had previously worked with Devise for a Ruby on Rails app, and it's perfect for what I need here. I need to have a local (as in not hosted on a third party server) user database, email confirmation, forgot password, etc, and Devise was able to handle all of this gracefully. I have looked at Xamarin.Auth but it only mentions OAuth. Is there anything for C#/.NET/Xamarin that is functionally equivalent to Devise? I haven't found anything on Google, and the closest SO question I could find was this Authentication engine for ASP.Net MVC like Devise for Rails? but it's both old and it doesn't really provide any good solutions, and I was wondering if something may have changed in the meantime.

Since you're in the C# / NET stack, I would recommend Identity Server 4. It is an OIDC provider, you can also use it as classic authentication service using username/password.
You are looking for the Resource Owner password flow, which requires invoking the Token Endpoint of this service.
While I wouldn't suggest rolling your own authentication, sometimes there's a need for it. In that case, choosing a mature and standardized solution is the best way to move forward.
Identity Server 4 is an OIDC compliant, highly configurable and scalable .NET option.

Related

Implement custom token-based authorization/authentication system

I am trying to migrate one of our solution from a Laravel/PHP system to a .Net Core 2-based system. My main problem is regarding Authorization and Authentication.
I have 5 different apps that send REST queries to the Api (e.g. Web Browser, iOS Apps, Android Apps, etc.) and the way I currently handle authentication/authorization is as follows:
A user sends a Username/Password, as well as an App Id (e.g. 'Browser', 'iOS', etc.) and an App description (e.g. 'Chrome-Jacob', 'iPhone-7-Jacob').
If a Token already exists for the pair of App Id / App Description, it is returned. Otherwise, a new token is generated and saved in a Database table named 'Tokens'.
Each token can have a different matrix of permission, which is very granular (e.g. 'Users/ViewAll', 'Users/Create', 'Users/ViewOne', 'Users/ViewMe', etc.)
When a REST query is received with the token in the header, we look for the token's permission matrice in the database and try to see whether the intended feature to be accessed is authorised or not.
It seems that in Core 2, the intended use of token is through JWT. I'm not 100% comfortable with this approach, because I want the user to be able to see all tokens that were generated for his access, all associated permissions and the ability to simply revoke access to a token; whereas with a JWT, it is impossible to know who has what token, until they send it in a request.
My current implementation can generate any random token as long as it's unique in database; it doesn't necessitate any encryption algorithm.
What would be the best approach to replicate the system above in Core 2 ?
I find Microsoft's approach very good for simple applications but I am struggling to override the Authorize Attribute and get the granularity that I wish for.
I find Microsoft's approach very good for simple applications but I am struggling to override the Authorize Attribute and get the granularity that I wish for.
That's quite the opposite. Microsoft did not invent nor were close to the first to start using JWTs. You have taken something that is very common and made your own version of it, something that's not considered secure nor a good practice.
There are two ways to solve the problem at hand:
Using Identity Server 4, a free, open-source system made for ASP.NET Core, made by highly experienced security people, which provides you a customizable OAuth 2.0 / OpenID Connect system. With this, you would need to rework, some parts of the security of the applications, but you would be using industry standards.
Note: this might not be too easy, but scales extremely well
Identity server already gives you all the information about each application and which tokens are valid for which.
While you could do this by hand without too much trouble, I would suggest you to look at ASP.NET Core Identity, the official framework for Authentication and Authorization in ASP.NET Core. Notice that, regarding how to know which tokens/logins are active, Identity recently adopted two interesting tables:
IdentityUserLogin: tells you what users logged in where/how
IdentityUserToken: gives you the tokens that have been provided for a given user.
All this said, it's common to add ASP.NET Core Identity to an Identity Server 4 application, given that the later is not for handling authorization.

Posting a SAML token to ASP.NET MVC website

I have a claims aware MVC website setup using the Thinktecture Identity Server. I now have a requirement to allow a 3rd party to access certain parts of the website.
Is it possible to programmatically authenticate with the Identity Server and post this to the website so that the user at the 3rd party is not required to manually go through the normal login process?
I have previously used the identity server to obtain a SAML token for the purpose of making WCF calls, I was wondering if it would be possible to re-use some of this approach?
The complications arise from the fact that the 3rd party are using a desktop based Java app with some browser component built in for accessing the MVC website. Users are already authenticated with the desktop app so we don't want them entering credentials again to view these web pages.
Hmm, tough one to solve in a secure fashion. Basically I don't trust desktop apps ;-)
You might be looking for some sort of federation. Basically it is about letting your Identity Server trust the 3rd party (by means of signature). Your Identity Server would then use a SAML token from 3rd party as login information and generate a new SAML token (signed by you) to forward to the the MVC web application. I think Dominick has a video or two about it, but not sure it meets your requirements. Take a look at https://github.com/thinktecture/Thinktecture.IdentityServer.v2/wiki
The Java desktop app probably cannot create a signed SAML token, so you could consider using "something else". Preferably something signed from where they logged in the first time.
You should avoid having your web app trust anyone but your own Identity Server / Identity Provider.
Hope this helps? Happy to help where I can :-)

REST service authentication

What are the best practice for implementing authentication for REST apis?
Using BASIC auth + SSL or something like https://datatracker.ietf.org/doc/html/draft-hammer-http-token-auth-01?
Are there any existing solutions available (for .NET / WebApi)?
The answer on this depends on the audience for your Web API and what you want to authenticate exactly.
Do you want to authenticate a client application that uses your Api?
Do you want to authenticate a user from your application to retrieve their data within a client application (using your Api)?
Or do you want to authenticate both the client application and the user using the client application.
Depending on what you want to authenticate you have multiple options. But always keep in mind that it is better to go with a solid solution where many client libraries are available than reinvent you own. Never do a little off this, but in your own way, chose one way of authentication, stick to it and don't break the client libraries.
Basic authentication: Is very easy to implement, but you authenticate a client app with it, not a user. This kind of authentication is nice when business trust relation needed and authentication and safety is not your very first concern. But there is no way to track a call in your API back to a certain user, just a client application. Of course you could save your user's username and password in a client application but this is a bad practice in more then a single way.
Token based authentication: Their are many ways of token authentication but the one i'm talking about here is a single token for a user which the user copies to the client application to get access to your Api. This way you can authenticate a user (who made this call in my Api?) And it is fairly easy to make and use. The withdrawal is that it is not the most secure way, requires user interaction and that a user possibly uses his Api token in more then one application. You could extend this way of authentication with basic authentication to authenticate a client. So a clientid + clientsecret + token to identify the user. But I think if you want to accomplish this it would be better to take a look at Oauth2.
OAuth2: If you want to have full access over your authentication you can go this way. It is possibly the most future proof way to go, but also requires the most work (at least at the identity provider/resource provider side. The client application has a fairly easy time implementing this with a lot available client libraries. If you go with this way of authentication (also token based) you can authenticate the client and the user, without the need to share your users username and password.
My recommendation: would be to go with Basic Authentication if this fits your case, it is easy and together with HTTPS is fairly safe. If it doesn't fit I would go with Oauth2 because it is the most solid and used standard (Instagram/Google/Facebook), gives you a lot off freedom and with a growing ecosystem gets easier and easier to implement. After all for someone implementing your API it is way more interesting to learn something about Oauth 2.0, then learn about the jgauffin way of doing things.
Reference: I would also like to invite you to have a look at Apigee's website. Api's are their business and they have quite some interesting reads. One of them is is a free ebook - Oauth the big picture which also has a interesting paragraph where they ask if you really need Oauth. (From page 16 - Is OAuth all you need for API security?)
For server-to-server APIs - APIs designed to be used only by a small number of servers –
OAuth is overkill. Having a separate set of authentication credentials for each app is a nice
feature of OAuth, but for server-to-server use, the need to log in securely using a browser,
or to implement other steps in the OAuth “dance,” gets in the way.
Instead, using a simple security standard like HTTP Basic authentication and assigning a
unique password to each app is sufficient. Two-way SSL is another good, albeit
cumbersome approach that has the advantage of stronger, more traceable authentication.
However, think ahead! Are those APIs really only going to be used by servers forever?
Exisisting Solutions: Whatever way you go leastprivilege - Dominick Baier and his nuget packages can give you a nice headstart. Implementing basic authentication using his Identitymodel is really easy. Also if you want a ready-to-go identityserver to provide you with tokens look at his identity server which does all you can think off. However if you decide to go for Oauth2 I would also have a look at DotnetOpenAuth since it is (imho) a bit more configurable and easier to tweak to your own like, but it also takes more work.
You should look into Security Token Service or STS.
Check out these links for more information:
Off-the-shelf Security Token Service (STS) that uses ASP.NET membership provider?
http://msdn.microsoft.com/en-us/library/ee517259.aspx
You could have a look here, IdentityModel has Web API support:
http://thinktecture.github.com/Thinktecture.IdentityModel.45/

Using Google federated login with Google Apps and ASP.net application

As an organisation, we use Google Apps. We have the paid version (mapped to our domain) etc...
We are developing a web based application to manage orders, and other business functionality.
I want to be able to use federated login with our google apps accounts-
For example, if a user is logged in to their email (gMail) - they should automatically be logged in to our ASP.net application
If they're not logged in - the log in form should auth. against our google apps account.
How can this be done?
Is it possible to be able to "get" the user who is currently logged in using this method etc...?
Sure, use dotNetOpenAuth. It's recommended by OpenId library and it should be easy in use. As far as google provides OpenId interface there should be no problem with using it in your application.
Stackoverflow is successfully using it and I'm logged here always when I'm logged on my google account.
Just doing a quick search through Google's API documentation, it sounds like you need to use Google's implementation of OAuth protocol.
If you have not yet started developing, you could even considering developing for Appengine - using python or Java (though I would prefer Python myself).
Advantage is that it has a much closer integration with Google Apps services and it will be much easier to build further functionality that works with Google apps (docs/mail etc). Besides this, there arent too many hassles for hosting the app.

Forms Authentication

I've been programming for a long time now, but I'm not the world's most experienced.Net developer. I recently picked up a project that is using Forms authentication for their website. I first looked at forms authentication in .Net 1.1 and at that time it had some limitations that made me decide not to use it as my primary form of authentication.
This project requires that users have roles (which I understand forms authentication supports) and group memberships. For example "User A" is an "Admin" for "Company A". Does forms authentication now support this sort of user structure?
I've also read that forms authentication sends passwords back as plain text. This client does not use SSL. Is this true?
The current code base uses forms authentication, but does not support groups (it does support roles). So, I need to either modify the forms authentication to support the required groups or rip out the forms authentication and use the Authentication framework I normally use. If forms authentication does support groups and is secure enough, then I should stick with that. If forms authentication has security issues or does not support groups then I need to remove that form of authentication.
I've searched the internet for a pros-and-cons sort of article, but no luck. What do you guys think?
To satisfy you requirements you will use Forms Authentication with Membership. If your application is using SQL Server database you can use SQLMembershipProvider as the membership provider to achieve this.
Examining ASP.NET 2.0's Membership, Roles, and Profile can be a good start reference.
About your concern about sending passwords as a plain text when the connection is not secured.
Actually the passwords that are sent are usually hashed (algorithm will depend on the Membership Provider chosen) and that is as there are eventually stored.
Of course if the connection is not secured that hashed password can be retrieved and used to hack the application but at least you eliminate the possibility that the plain user password is stolen and used e.g. to access another service (as you know many people use the same password across multiple services). So to be secure you really need to use https here.
As a note of warning, I am far from being an expert in that field, but quite recently I was faced with a similar problem that you are describing so I though that you may find some of this useful.
Forms authentication doesn't sends passwords back as plain text. As long as you make sure the login/pwd is protected when receiving it (i.e. using https ... ssl) there is no security risk in there.
If you really need to do authorization that way, you can rely on forms authentication for ... authentication, and do authorization with your own mechanism.
Forms Auth is an excellent choice for what you're after. It does support roles but it does not support groups. However, it does have built in support for active directory integration, which you can use to aleviate the group issue, if necessary. Personally, I would stick with what you have and learn more about it. If you want to use Forms mode of Forms Auth rather than AD auth mode, I would consider building on group support using the existing forms auth database.
I highly recommend viewing these videos from Microsoft about forms authentication. You'll find that it's pretty straight forward to use. Granted, it's not something you can throw together as it is a fairly robust and flexible framework. You'll want to read up on it and view these videos. However, when you become familiar with it, you'll find that it's secure, supported and very well accepted by the development community.
Yikes, I just reviewed your question again and you said they don't use SSL. How secure does this site need to be? To me, that would be my first order of business is to move to SSL!
Forms Authentication will not support groups natively. What we do is use it to "authenticate" a user (prove who they are) and then we use our own data stores to "authorize" a user (describe what they can do).
the db doesnt store the plain password text it uses md5 or some other means of hashing... i know that they are matching 2 hashed strings against each other to auth wheter they convert the string client side or server side im not sure..its probably browser... if you are thinking about using ssl i dont think you should be using ASP.net forms auth... its time for you to do your own forms based auth and dive in to some ad mining....
Thanks for all of the input. Although I think I'll continue to use my own authentication library in other projects, I think that the best thing to do for this client is to stick with the forms authentication they already have partially in place.
Although I develop with Visual Studio and the .Net platform, I don't always like to do things the "Microsoft" way. I find that many times the "Microsoft" way introduces a lot of overhead that can be avoided if you know what you're doing.
Thanks again for the input.
Passwords have to be passed clear text over the wire if you are not using SSL. Hence the need for SSL.
.Net Forms Authentication will properly hash and store the password to the db however this won't protect the credentials over the wire. But this holds true for all web frameworks.
As for the group piece of this you'll have to implement this in your app or find some libraries to help you.

Categories

Resources