Dropbox OAuth 2 dynamic return URL - oauth-2.0

The Dropbox OAuth 2 requires me to set a return URL. Is it possible to implement the OAuth 2 flow with a dynamic return URL?
Background on why I need the return_url to be dynamic: The flow works great if the integration is through a website, however I am working on a product which is managed through a web console, and typically users will access it using the private IP on the unit. This IP is something I cannot know in advance.
Possible Solutions if dynamic return URLs aren't possible:
I host a cloud service of some sort to act as a broker --- the broker is a fixed URL and I relay back the access code to the device.
Use OAuth 1, which doesn't seem to have this restriction.

Florent's comment is correct, this isn't currently possible, as all OAuth 2 redirect URIs are required to be pre-registered as a matter of security. I'll be sure to pass this along as feedback though.
As mentioned though, one thing you may be able to do instead is to use one static redirect URI but encode the necessary information in the 'state' parameter, and decode it as necessary after the redirect back to your app, to handle it as necessary:
https://www.dropbox.com/developers/documentation/http/documentation#oauth2-authorize
Alternatively, you can use OAuth 1, which doesn't require pre-registered redirect URIs. Edit: note that OAuth 1 is only available for API v1, which is now deprecated.

Related

Is it possible to use recaptcha with auth0 in some way to avoid having a user to sign in but still have a token?

I have an app, client side, that uses auth0 for accessing the different API's on the server. But now I want to add another app, a single page app, I'm going to use VueJs, and this app would be open "ideally" w/o a user having to sign in, it's like a demo with reduced functionality, I just want to check that the user is not a robot basically, so I don't expose my API in those cases.
My ideas so far:
- Somehow use recaptcha and auth0 altogether.
- Then have a new server that would validate that the calls are made only to allowed endpoints (this is not of my interest in the question), so that even if somehow the auth is vulnerated it doesn't leave the real server open to all type of calls.
- Pass the call to the server along with the bearer token, just as if I was doing it with my other old client app.
Is this viable? Now I'm forcing the user to validate, this is more a thing about UX (User-experience), but I'd like a way to avoid that. I'm aware that just with auth0 I can't do this see this post from Auth0, so I was expecting a mix between what I mentioned.
EDIT:
I'm sticking to validating in both cases, but I'm still interested to get opinions over this as future references.
At the end, with the very concept of how auth0 works that idea is not possible, so my approach was the following:
Give a temporary authenticated (auth 0) visitor a token which has restricted access level, then pass the request to a new middle server, the idea is to encrypt the real ids so the frontend thinks it's requesting project A123456etc, when indeed it's going to get decrypted in the middle server to project 456y-etc and given a whitelist it will decide to pass the request along with the token to the final server, the final server has measures to reduce xss and Ddos threats.
Anyway, if there's a better resolve to it I will change the accepted answer.
You could do a mix of using recaptcha for the open public, then on the server side analyse the incoming user request (you can already try to get a human made digital fingerprint just to differentiate with a robot-generated one) and the server (more a middle server) makes the call to you API (and this server has limited surface access)
What we normally do in these situations (if I got your issue correctly) is to create two different endpoints, one working with the token and another one receiving the Recaptcha token and validating it with Google servers.
Both endpoints end up calling the same code but this way you can add extra functionality in a layer in the 'public' endpoint to ensure that you are asking only for public features (if that cannot be granted just modifying the interface).

WWW-Authenticate schemes for OpenID Connect

I'm writing my own codes for the OpenID Connect protocol. Basically, I intend to write my own provider and related stuff on Google App Engine's platform using Jersey and Google's datastore via Objectify library.
I'm in the middle of implementing the (access/refresh) token endpoint and there's this client authentication that I need to take care of. I'm just wondering if there are preset authentication schemes' keywords that I could send if in case the client did not have client_secret_basic set during the registration process (or whatever's set in the datastore entry.)
For a failed client authentication with the following methods, the scheme is used as response in the WWW-Authenticate header (401):
client_secret_basic: Basic,
client_secret_post: ???,
client_secret_jwt: ???,
private_key_jwt: ???,
none: obviously none.
I've looked at some open source implementations, nimbus' and OAuth-Apis', but they don't seem to handle this minor issue (they only respond with the generic error response defined in OAuth2 rfc6749#section-5.2.)
If there are no predefined keywords, then I suppose I'll have to make up my own. But it would be great if they exist.
The authoritative list for these is at IANA. There, you can find these handfuls:
Basic
Bearer
Digest
HOBA
Mutual
Negotiate
OAuth
SCRAM-SHA1
SCRAM-SHA-256
vapid
Which of these is client_secret_post, client_secret_jwt and private_key_jwt? None. You'll need to map those to one from the registered list above or return your own values. Better yet, you can submit a draft to the OAuth working group or the OpenID Foundation to get the above IANA registry updated with something that makes sense for these missing cases. Then, we can all interop :-)

Linkedin OAuth2.0 : How to configure OAuth 2.0 Redirect URL with a wildcard subdomain url for a multi tenant application

I am trying to configure a LinkedIn application for a multi tenant site. I will have 20+ tenants using the same application and the number is going to increase every time.
As per Linkedin API documentation (https://developer.linkedin.com/docs/oauth2) we need to ensure following points
We strongly recommend using HTTPS whenever possible
URLs must be
absolute (e.g. "https://example.com/auth/callback", not
"/auth/callback")
URL arguments are ignored (i.e.
https://example.com/?id=1 is the same as https://example.com/)
URLs
cannot include #'s (i.e.
"https://example.com/auth/callback#linkedin" is invalid)
Can i configure redirect url as https://*.mysite.com/auth/linkedin/callback instead of specifying url of each tenant separately.
You cannot do a subdomain based wild card mapping as the IP should know the RP.
You can change the logic after you get the authorization callback, so you set the cookie and then you will have to redirect the user back to the tenant URL instead of the base URL.
Anyway, after successful authorization, you will be redirecting the user to an action, just figure out the subdomaina and the construct the URL and do the redirection
HTH
EDIT
Since the use of the URL or other approaches seem to be a hack, can you please try to have a facade like application (or Gateway like one) that has a URL that is registered in linkedin and then on receiving the response, it can use a state or other factor to redirect to the tenant URL. This can use a 302 and it will be invisible unless the user is on a very slow network. This approach does not require any hack like approach.
Here state can be a function that takes a tenant info and generates a dynamic hash that is stored for tracking and redirection.

AngularJS and authentication to an Oauth2 Provider?

We have an API, Oauth2 Provider.
From AngularJS client Side app, how can I implement the flow of authentication to this api to get the access token for future requests?
What I am searching for is a Implicit Grant flow for this.
I'll provide a
{
client-id: "abcdefghijklmnopqrstuvqxyz0123456789",
redirect_url: "http:localhost:8080/provider_cb",
response_type: "token"
}
I have a Rails REST API in the backend and doorkeeper/devise for Oauth2 provision.
I came across angular-oauth, which seems to solve the problem to certain extent.
but,
I do not wish to provide a token verification function (Is this mandatory)
I do not wish to open a new window popup for the login (Wish to do redirections in same window)
Now,
Q1. What I do not understand is how is the whole process started, I can't make any $http request, this returns with a SignIn HTML page. Should I use $location service to redirect to it to login page? Or should I have a link to the whole GET request to /oauth/authorize?...
Q2, How will I capture the redirect after SignIn to extract out the access_token?
Q3. Do know any Service which takes care of Oauth2 authentication or a standard Angular way of doing this?
Lets try an answer to your three questions:
Q1) You should basically understand the general OAuth2 process. It is not an AngularJS-specific implementation you're looking at. If you don't want to work with a popup window for the authorization, you'll have to trick around a bit to have the redirect_url / state working correctly after coming back (if you want to have #state - saving - otherwise just specify your entry - url in the redirect_uri). You should not use $http for the redirection as this is just for XHR and similar calls useful. To get your user to the login page, just do a
$window.location.href = 'http://yourlogin.com/oauthloginpage';
Your app will then redirect to the login page - don't forget your parameters for redirect_url. Also specify other parameters within the request like "scope" / "state" if required.
Q2) The redirect AFTER Login will redirect to the uri you specified within your redirect_url. Then it will come up with something like http://myapp.com/#access_token=foobar&refresh_token=foobar2&state=loremipsem
Just grab the parts from angular with a bit of code like this:
var currentURL = $location.absUrl();
var paramPartOfURL = currentURL.slice(currentURL.indexOf('#') + 1);
Then parse the paramPart into an array with split('&') and iterate through it by looking for the "key" access_token and - voila - there is your access_token ready for being taken into your local storage / service / cookie.
There are other implementations you might use to split URLs into parts - maybe there is a better one, but this here would be the "fast shot".
After parsing, you can redirect the user again to the correct state with a normal $location.path(....) call and eliminate the # parameters of OAuth2.
Q3) If you want to have a way of mapping the source state / route of your AngularJS-app - try misusing the state parameter if your OAuth2-Server implements it. This will survive the request <-> response.
For a non-popup-implementation, I don't know any further module currently.
Another way to play with the OAuth2 stuff is to implement the loginpage on your own and then just interact with a oauth2 provider reacting on rest calls with Basic Auth or other methods. Then you can use $http calls probably.

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

Resources