Alternative ways to authorize use of surveymonkey account? - c#

After I redirect to the OAuth dialog page, is there a way to authorize use of my account programmatically? Right now, once I enter my username and password, I can get the authorization code and the rest of my app works perfectly, but I want it to automatically authorize use of my account.
Edit: the user will never see any of the account information of course, but according to the api, in order to get the authorization code you need to authorize the account

The OAuth system is designed so that you cannot log in programmatically, you must display the dialog box to the user for them to log in to SurveyMonkey. However, once a user has logged in once you can then store the access token returned by /oauth/token, and use that to access a user's data whenever you need to.
If all you need to do with your application is access your own data, just store that single access token. When you retrieve it, it is returned in a JSON blob that also defines its expiry - currently SurveyMonkey tokens do not have an expiry (unless a user revokes the access token), so until that changes you can use this access token for as long as you require.
I would suggest checking out the SurveyMonkey OAuth guide for more information: https://developer.surveymonkey.com/mashery/guide_oauth

Related

In Azure Active Directory authentication why is authorisation code flow used

I am working on a .net MVC and web API project and using active directory to authenticate users to API, on authentication, a code is being returned from AD and I have to exchange the code to obtain a token and use that token to call the API, the question is why is the code returned and why do I have to exchange it for the token? can I directly obtain a token?
This is all because of security reasons.
OAuth 2.0 wanted to meet these two criteria:
All developers will not have an SSL enabled server and you should allow them to use non-HTTPS redirect URI
You don't want hackers to be able to steal access/refresh tokens by intercepting requests.
Since the Authorization Code grant has the extra step of exchanging the authorization code for the access token, it provides an additional layer of security not present in the Implicit grant type.
According to Nate Barbettini we want the extra step of exchanging the authentication code for the access token, because the authentication code can be used in the front channel (less secure), and the access token can be used in the back channel (more secure).
Thus, the security benefit is that the access token isn't exposed to the browser, and thus cannot be intercepted/grabbed from a browser. We trust the web server more, which communicates via back channels. The access token, which is secret, can then remain on the web server, and not be exposed to the browser (i.e. front channels).
For more information, watch this fantastic video:
OAuth 2.0 and OpenID Connect (in plain English) https://youtu.be/996OiexHze0?t=26m30s (Start 26 mins)
Your question isn't really specific to Azure AD, and is more about the OAuth flow and why it is used.
The flow seems a bit complex, and well, it is, but there are reasons for all the things it does.
I encourage you to use authorization code flow instead of other approaches.
It has many advantages:
Your app will never see the user's password
The user cannot see your app's client secret
The user cannot see your app's access tokens (and neither can a man-in-the-middle attacker)
You get a refresh token that you can use to get new tokens whenever needed (you do need to specify the offline_access scope for this though)
The user can go through multi-factor authentication, federated authentication with ADFS etc., and your app doesn't need to care about that
Alternative flows and their downsides:
Implicit flow
Gives you a token directly without the code exchange
There is no refresh token
Mainly used in Single Page Apps, where refresh is done using a hidden iframe, but that depends on the user's session remaining active
If you use this outside a SPA, you can't really refresh the token, requiring the user to login again every hour
User can see and take your app's access tokens
Client credentials flow
Instead of accessing the API as a user, you access it as the app itself
Some APIs do not support this approach and require you to make calls on behalf of a user
This doesn't allow you to authenticate a user
Application permissions are needed to use this flow, which usually give very broad access to the entire organization
The upside of this flow is that it is very simple
Resource Owner Password Credentials flow
Do not use this flow
HTTP request to token endpoint with app + user credentials
Exposes user password to your app (!)
Does not work if user has MFA, expired password etc.

Windows Service connect to Azure AD as User (MFA)

I have a service which needs to run under user context, because some endpoints of Microsoft need an user context to execute. My problem now is 01.09.2019 MFA is mandatory. So, at least at the beginning, the service needs a person who logs in, but this is not possible because it is an non interactive Windows Service. So my question is, it is possible to login as a user by code or not? If it is, how? And will the refresh token be stored in the aad cache?
UserIdentifier user = new UserIdentifier(Cred.UserName,UserIdentifierType.OptionalDisplayableId);
return Task.Run(() => authContext.AcquireTokenAsync(
"https://api.partnercenter.microsoft.com",
Cred.ApplicationId,
new Uri("http://localhost"),
new PlatformParameters(PromptBehavior.Auto),
user)).Result;
You'll need to have some kind of app that authenticates the user and stores their refresh token in a secure place like an Azure Key Vault.
Your background service can then use the refresh token to get a new access token and new refresh token.
You can use the access token to call the API and store the new refresh token over the old one.
Then if the refresh token does not work, you'll need to repeat the authentication process.
Refresh tokens can go invalid for some reasons, so your app needs to be ready for that.
it is possible to login as a user by code or not?
yes it is possible
In Authentication time the app receives both sign in info (the id_token) and artifacts (ex: an authorization code) that the app can use for obtaining an access token. That token can be used to access other resources -
This sample shows how to use MSAL to redeem the authorization code into an access token, which is saved in a cache along with any other useful artifact (such as associated refresh_tokens) so that it can be used later on in the application.

Parsing 'wresult' value without WSFederationAuthenticationModule

When returning from Azure ACS I retrieve a federation authentication result inside a FormCollection. The value containing the information I need is inside an encrypted value called "wresult". I'm having problems decrypting this value to use it for further authentication.
I don't want to use the WSFederationAuthenticationModule because I don't authorization cookies to be set. When the module is used, it'll automatically set auth-cookies with the Federated-Authenticationtype.
I instead want to retrieve the claims contained in the wresult and then set my own security token (be it JWT, SAML 2.0 or whatever).
The only possible workaround I found so far is to use the FAModule, and then delete the session token cookie right away. But this will result in the auth-cookies to be set twice in the response, with the value and right away unsetting it.
What I want to achieve in the end is the following:
Providing the possibility to either authenticate with a forms site, or authenticate using any identity provider in Azure ACS. Using the forms authentication I can compare the username and password right away and set the security token with whatever claims I want it to have. But when using Azure ACS, I want to compare the retrieve nameidentifier with saved values in my database first, and then set my custom security token, instead of the WS federation one. Or in case the nameidentifier is unknown, I want to redirect to a forms page where the user can authenticate this nameidentifier with his credentials. I don't want the azure ACS returned value to be calculated as authenticated.
You don't have to register the FAM - but you can still use its helper methods (e.g. GetSignInResponseMessage()) to parse the sign-in response message from ACS.
This gives you access to the protocol details and the returned security token without having to use the WIF cookie system.
Instead of modifying WSFederatedAuthenticationModule's default handling of cookies, I would suggest an alternative setup:
Create and host your own forms based auth identity provider STS. There are some nice options to help set this up.
Configure your new IP STS in ACS
Use the default ACS login page (home realm discovery page) or customize your own.
Now your users will get asked to choose which identity provider they want to authenticate with. If they choose yours, upon entering a username/password, your IP will send a nameidentifier to ACS, which in turn sends it to your relying party website. Same goes if you add google as an identity provider. The benefit is your RP doesn't need to behave differently depending on what IP the user logged in from, but if you want to customize some behavior based on the IP, that information is available in the token issued by ACS.
Also, if you want to use JWT tokens instead of SAML, you can configure ACS to issue them from your relying party page in the ACS portal (though this is marked as beta functionality).

Facebook Graph API: Have app access token, need user access token without interaction

We have an audio blogging website which can be configured to publish links to the user's Facebook timeline whenever they make a new blog entry.
To do this, we have the user authorise our app when they set up the link to their Facebook account. We obtain the publish_stream, offline_access and manage_pages permissions (more on that later).
All the code is in C# but the principles apply to any language as it's the workings of the Facebook API we are concerned with. We're using OAuth 2 and the Graph API to achieve all of this.
So, we obtain an app access token using our app ID and secret and use that token to publish to the user's timeline, this works fine (because they have already authorised our app to do this). We can also query the Graph API and get their likes, friends and various other data.
NOW HERE IS THE PROBLEM:
Some of our users want to publish updates to their own timelime and also to the timelines of pages that they manage. In theory this is simple: you query the API for the pages that the user manages using this url: https://graph.facebook.com/{userid}/accounts?access_token={token}
The JSON returned from this call is said to contain the page IDs and the page access tokens for those pages. You then use the page access token to publish to the pages' timelines.
However, when we try to call this URL with the app access token we are getting an OAuthException 102 "A user access token is required to request this resource".
Note this is different to OAuthException 104 "An access token is required to request this resource" (which is what you'd get if you neglected to pass an access token), and also OAuthException 190 "Invalid OAuth access token signature" (which you would get if the access token was not a valid one).
So our access token is valid, but just not valid for this particular url. It seems therefore that we need a user access token and not an app access token for this particular feed (I am long past caring why this is the case, it just seems to be the way it is).
All the Facebook documentation on this subject (and I must have read all of it by now) leads to one place: http://developers.facebook.com/docs/authentication/server-side/, aka the "Server-Side Authentication Flow" page. This page describes how to get the elusive user access token by redirecting the user to the auth dialog and asking for the relevant permissions but we need to achieve this without interaction from the user and the user has already given our app all the permissions we need. All of this automated publishing happens server side in the post-processing of the audio so we cannot interact with the user at this stage anyway.
I don't get it. Why is it we can use the app access token to get almost any data we want from the user (well, whatever they have given us permission to get) but the /accounts data we need a different (user) access token for?
Can anyone shed any light on how we can get a user access token which will allow us to get the /accounts data for our users without any further interaction from the user?
So our access token is valid, but just not valid for this particular url. It seems therefore that we need a user access token and not an app access token for this particular feed
Due to the permissions per type of access token, you do need a valid user access token in this particular case. Read all about access tokens and types. That's just the way it is.
This page describes how to get the elusive user access token by redirecting the user to the auth dialog and asking for the relevant permissions but we need to achieve this without interaction from the user and the user has already given our app all the permissions we need.
If your user already has given his/her permissions, why are you struggling then? I suggest you persist the user access token. From this endpoint:
https://www.facebook.com/dialog/oauth?client_id=..&redirect_uri=..&state=..&scope=..&response_type=..&display=.."
you retrieve a code, like this:
YOUR_REDIRECT_URI?code=OAUTH_CODE_GENERATED_BY_FACEBOOK&state=YOUR_STATE_VALUE
Use this code to generate your user access token, as explained here:
https://graph.facebook.com/oauth/access_token?client_id=..&redirect_uri=..&client_secret=..&code=..
This will result in a response like:
access_token=USER_ACCESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES
There it is, your user access token. Persist it. As you can see it expires after the value indicated in the response. If you are using the new API, it should indicate 60 days (that brings me back to this: offline_access is deprecated and results in short-lived - valid for 2 hours - tokens), link. Whenever your user logs in to your app and uses the Facebook integration, the tokens gets refreshed to again, 60 days. This means, that IF your user should not login to your app and use it for 60 days, it will expire.
You can check whether the user access token is expired with:
https://graph.facebook.com/debug_token?input_token=INPUT_TOKEN&access_token=ACCESS_TOKEN
If that does: renew the user access token by using your app access token, it is well documented right over here. But I'm quoting this part:
Server-side Login
To obtain a fresh [user] access token in this case you must pass the user through the full server-side Login flow again. However, assuming the user has not de-authorized your app, when you redirect the user to the OAuth Dialog, they will not be prompted to reauthorize your app, and will be immediately redirected to the redirect_uri. This means that the re-authentication process can appear reasonably transparent to the user.
Bottom-line: there are no user access tokens that are valid for ever, the app access token however is. Persist your user access token and check whether it is still valid before performing API calls with it. A normal user should use your app within 60 days and should not just de-authorize your app for fun. Hence the use case in which the user should re-authorize is fairly rare, however, you need to expect it.

Posting info to Twitter with a known username / pass and the Oauth token without having to grant access

I'm using C# to build some functionality for a website. They want to twitter a message to their account at the point when a new vacancy gets added to their website. I face the issue that when i try to do this using the OAuth token approach i have to grant access to the application everytime. I want this all to work automatically without the need for permission. Can i login the user and then just post a message or how do I approach this?
With OAuth you only need to get their permission once, and you can save the Access Token that Twitter returns to you and use it to act on behalf of the user as long as the user does not deny you permission to act on their behalf or the token hasn't expire. Twitter does not currently ever expire tokens see Twitter OAuth FAQ.
Just save the token along side the username in the database and use it to send post requests whenever you need to post to twitter.
Twitter puts it this way in this Transitioning from Basic Auth to OAuth Guide:
Prepare long-term storage for access tokens and secrets
Whatever your storage system may be, you'll need to begin storing an oauth_token and oauth_token_secret (collectively, an "access token") for each user of your application. The oauth_token_secret should be stored securely. Remember, you'll be accessing these values for every authenticated request your application makes to the Twitter API, so store them in a way that will scale to your user base. When you're using OAuth, you should no longer be storing passwords for any of your users.

Categories