Can anybody explain OAuth? - c#

I've read a bit about it at http://oauth.net/ , it's "a simple way to publish and interact with protected data" apparently.
I think it's exactly what I need to provide a secure way of accessing data from an android/iphone app via a REST web service, but I can't work out exactly what it is.
So, put simply, what exactly does it do and are there any (really) simple examples of it in action I can follow, preferably implementing something in c# that can be accessed from a smartphone app?

From the link provided by Craig Stuntz:
Open ID gives you one login for multiple sites. Each time you need to log into Zooomr – a site using Open ID – you will be redirected to your Open ID site where you login, and then back to Zooomr. OAuth lets you authorise one website – the consumer – to access your data from another website – the provider. For instance, you want to authorise a printing provider – call it Moo – to grab your photos from a photo repository – call it Flickr. Moo will redirect you to Flickr which will ask you, for instance, “Moo wants to download your Flickr photos. Is that cool?”, and then back to Moo to print your photos.
DotNetOpenAuth is a good C# library for Open ID and OAuth.

OAuth is an alternative way for applications to keep login data without having the real data stored at all.
When you log into some page, you usually have a username and a personal password, or any other sort of login credentials. Now, if you want an application to be able to do stuff over that login, you would need to give that application your original login data. Which means that you enter both your username and your password into the application. That isn't bad so far, but the thing is that if you want to stay logged in via that application, it needs to store your credentials. But to make it possible to send the correct login data to the actual page, it needs to store those in their original form (just with some encryption or something). So if someone knows how the data is stored in the application, they can extract your original login credentials.
This is a security issue and exactly where OAuth comes in. With OAuth, every application is identified by a consumer key and a consumer secret. Both are unique to the client and usually no user will ever get to see those (especially not the secret). Now when you want to allow your application to have access to the page, you start the OAuth authorization process. You simply login to the page and explicitely allow that special application (identified by the consumer key) to have access. If you do that, the application will receive another key pair, the access token and access secret. That key pair only works for your account and only works when used by the exact application (identified by the consumer key, and secured to be the original app by the consumer secret). Now all the application needs to store is that access key pair (together with the already stored consumer key pair) and it will have access to the page without ever seeing your original login data.
That way, nobody will be able to get your actual login details, and nobody else (or no other application) will be able to use the generated access credentials to access the page. And if you don't want the application to have still access, you can easily revoke the access key pair, so that the application won't be able to use it any longer.
So OAuth is just a way to protect your real login data. Apart from that it does not add any other level of security or something, it's just to secure your data.

Related

How to close user accounts from Admin API?

I want to close users (which I'm now successfully importing through Admin API) without their consent when they leave our company and their domain email gets deactivated.
I found the following methods that are related to closing users:
https://developers.docusign.com/docs/admin-api/reference/usermanagement/esignusermanagement/closememberships/
This one says: "This method requires user authentication. It will fail with an application access token." So it's a no go for me because I have no way to get the user's auth form a server-side background application.
https://developers.docusign.com/docs/admin-api/reference/bulkoperations/userimport/closebulkuserimportrequest/
It says "Given a CSV list of users, close their accounts."
But the API method does not accept a CSV file as a request parameter! There is no way to pass any user data to it.
Maybe I could use eSignature API instead of Admin API - it has https://developers.docusign.com/docs/esign-rest-api/reference/users/users/delete/
But that one says "userId string
The ID of the user to access.
Note: Users can only access their own information. A user, even one with Admin rights, cannot access another user's settings."
So, I'm not sure if even an Organization admin with their JWT token can use this method to delete other users? Anyway, most likely, this method will require another JWT token for eSignature API, which in turn will require more infrastructure stuff (config variables, keeping token alive) and I really would want to avoid that and stick to the Admin API only, if possible.
I'm using .net DocuSign nuget package, and I see that CreateBulkImportCloseUsersRequestAsync also has only OrganizationId as the argument. But I don't want to close all the users in the organization, I want to close them by IDs or emails, whichever is accepted by DocuSign.
How do I close user accounts properly? No matter, if it's a bulk or single-user method, as we would want to close them immediately for every separate account.
You cannot close user memberships (note that the term "account" is incorrect here) you can only disable them. You can contact support, but even they cannot really completely eliminate a user membership like it never existed. There are reasons why it must stay in a dormant state.
To explain the difference between users and accounts, here is a diagram:

Azure B2C One time access to secured API

I have a web app (rest API) on azure, and I have a B2C setup that is securing it, requiring you to be signed in to access the API. This is good, as i wanted the API to be restricted to members. Basically, the entire web app requires authentication, and will prompt you for a sign in.
Heres the problem - my app has users (who have accounts) and clients (who do not have accounts). These clients might receive an email about a new appointment being set up with one of the users - this email should have one or more links/buttons (ie, a button to Confirm appointment, one to Decline, and one to request a reschdeule) and upon clicking this link I would like to update a field in my database via the rest api, so the USER knows the CLIENT's response. The trouble is, since the client wont have an account, I have no idea how I can give them a link they would be allowed to go to, and have the update happen.
I have tried to do a bunch of research - ive looked into AD external identities with a one time passcode - but i cant seem to find any info on how i would actually get this to work for my purposes.
Does anyone know how I might implement this in azure? Is there a way to call to azure form c# to generate a one time authentication that i can encode into a URL or something?
Any thoughts would be greatly appreciated.
Thanks!
You could do an anonymous authentication by using a magic link. The users account won’t even need to live in the directory. The link can be short lived, and potentially one time use. We call it id_token_hint or a magic link.
Sample here
https://github.com/azure-ad-b2c/samples/tree/master/policies/invite
And reference here
https://learn.microsoft.com/en-us/azure/active-directory-b2c/id-token-hint

How to obtain credentials for Http Basic Authentiction

I'm writing a C# application and need to scrape some information from an rss page that only offers Http Basic Authentication.
This seems to leave me with two choices
Ask the user to input their credentials into my app (which has trust issues as the app is then a potential middleman attacker?)
Get windows to insert the credentials on behalf of my app somehow (does this facility exist?)
All the examples I've seen on SO have the username/password hardcoded in the app or passed in as parameters from somewhere unspecified. My use-case is I'd like to give this app to people who may not want to trust it with their password.
How is this usually handled? Thanks
Short answer: It is not possible with basic auth. It is generally not possible with the OS a the trusted instance.
Long answer:
The proper way to solve this would involve a procedure where your application hands control to the OS (Windows), which then asks the user "Do you trust application XY to use your identity?". After user acceptance, your application would receive a security token which you could use afterwards to make your HTTP request to get the RSS feed. The problem is, that the site in question does only accept basic auth. This means, that the "security token" is the base64-encoded username and password. So the username and password would be exposed to your application anyway.
The second problem is that the OS and the RSS site have to share a secret (i.e. an encryption key not available to you or anyone else not allowed to log in site users), to enable the OS to issue a secure token that is trusted by the RSS site.
How the problem can actually be solved
The default, real-world example for the access of web resources with third-party software on behalf of the user without knowing his password is OAuth, see for example the Facebook login flow. (However, this requires the website/resource in question to provide third-party access. As your question indicates, this does not apply for your use case.)
The pattern employed is the following:
Prerequisite: You need to register your application with the RSS service provider to obtain an application ID and an application secret.
Your application redirects the user to the login endpoint of the identity provider.
The user accepts (or declines) the access of your application to his identity and data (e.g. the RSS stream).
The identity provider redirects to your app
Your application receives a token which can be used to make authenticated requests on behalf of the user. This may involve additional steps like exchanging the token for another.
Alternative Solution (does not answer your question):
Sometimes (protected) RSS feeds can be accessed via secret user-specific URLs. Of course, the user would have to provide your application with that url.

Pass username/password from Windows Forms application to an ASP.NET web application

Here is the situation:
C# Windows Forms application
ASP.NET web application
Both authenticate with a custom user table in the same database (usename/password) and create a User object that is used throughout both applications
A user is logged into the Windows Forms application and we want to launch a URL to open a page in the ASP.NET web application in the default browser (IE, Chrome, Firefox, etc.). We want to pass the current username/password from the Windows Forms application to the ASP.NET web application in order to keep the user from having to log into the web application separately.
Based on our research, here are some options we have found (and the drawbacks):
Pass username/password in URL as QueryStrings and create the User object in the web application
Not secure (password visible in URL)
Create a temporary HTML page on the client machine that includes a JavaScript OnLoad function that POSTs username/password to the target URL and create the User object in the web application
(Could not find a way to POST data directly to a URL and display URL in default browser using C#)
Not secure (password visible in temporary page)
Create a "Handoff" table to store username/password with a key that gets passed to the page via QueryString and deleted from the table when the page loads and create the User object in the web application
Small potential for key to be intercepted (hackers)
Have a separate MongoDB that stores the User object and retrieve it in the web application
Separate software (MongoDB) running - additional point of failure
All of this is so that the user doesn't have to type their username/password twice to log into both applications.
Which one of the above options above would work best (most secure, least overhead/maintenance)?
OR
Is there a way to create a Forms Authentication ticket (cookie?) in the C# application that could be used by the default browser?
OR
Is there a better, secure method for handling this?
(edit)
OR
Is there a good argument for requiring the user to enter the username/password again to access the web application if they're already authenticated from the Windows Forms application? If so, can you provide links to references? Best practices, web security standards, etc.
You could salt+MD5 the password and send it simply with the URL.
However, you should point to a script on the server first, which authenticates the user and creates the appropriate cookies, and redirects to the desired page, now without the credentials in the URL.
edited: or basically do whatever you want to preserve the users' session
Unfortunately, as long as passwords are involved, you can't be 100% secure. Still, hashing a salted (salting is when you concatenate the password with some other string before hashing) password might be your best bet if somebody can get a visual on the passwords.
You generate the password hash, with salt.
You send it to be processed (I usually just put it into the URL of a separate script, but it's a matter of preference.)
You generate a hash with the same salt on the server and check it against the submitted one.
Authenticate the user and redirect to the original location.
In additional to what Máté Gelei has contributed, you could also include a timestamp in the Url and check to make sure the timestamp falls within a few seconds of current time. This is a little added protection and ensures the login attempt becomes invalid very quickly. Of course, you would want to somehow hide the purpose of this to make it a bit more secure.
This does not make it 100% secure, but it does add one more level of protection.

How to handle persistent login from in MVVM application?

I'm writing an application which displays a login form before it loads, and it sends a POST request to a web application which I previously developed.
I can send login details off and get returned a 200 message and can recieve data within that request. However I now wish to store this login after the application has closed, to allow the user to not have to login every time they open the application, or in this case when the computer is restarted. (It will run at boot however needs to maintain an application and not a WCF service)
I'm using HTTPWebRequest in C# to handle POST requests to the server, and I can make cookies on the server side. How do I let my application know about these cookies and store them in a secure way to allow persistent login for my entire application? I've looked at a number of ways to store cookies in C# such as these two links:
http://www.c-sharpcorner.com/uploadfile/mahesh/managing-cookies-in-a-wpf-application/
http://msdn.microsoft.com/en-us/library/dd920298(v=vs.95).aspx
However the code in the first link gave me an odd cookie:
"CSCUser2=test-username; android_developer_C:_width=243px; __utma=1.1718972007.1316996246.1316996246.1316996246.1; __utmz=1.1316996246.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); android_developer_reference_lastpage=/C:/AndroidSDK/android-sdk-windows/docs/reference/android/speech/RecognizerIntent.html"
So I'm not sure if that approach is best? Any pointers would be appreciated.
I think the CookieContainer (i.e. the MSDN link) is the correct way to set and get cookies (By the way: note that your question has nothing to do with wpf or mvvm patter. It is a general c# /.net/httpwebreuqest topic).
As for caching credentials on the user machine which can be used in subsequent sessions - there are several ways to do this. You can either store the user password in a secure location, or you can store a session key sent to you from the server. The advantage of the second method is that the session key is limited in time (e.g. one week), and after that they user will have to perform a new login. The session key can be delivered to you from the server out of band as a cookie, or with a specific API. Web applications are using cookies because they have no access to any persistent store, but your wpf application can store the password or the session key anywhere it wants.
I recommend you use the DPAPI to persist secrets on the user computer. Google for c# and DPAPI to see how to do it in .net.

Categories