I'm having difficulty using Nginx's http_auth_request_module with dynamic, user specific URLs.
http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
I need to authenticate (using OAuth 2) a user whenever they attempt to access their notifications. I've got an Nginx instance acting as a reverse proxy to an API (api.*) built on Django, and a Node server (notifications.*) for real-time notifications.
Assuming I can authorize requests (return 200 on success, 403 on failure) through my API at:
api.example.com/authorize/user_id/ 'Authorization:Bearer user_access_token'
And the user's request is:
notifications.example.com/user_id/ 'Authorization:Bearer user_access_token'
How would I dynamically take the user's request to the notifications subdomain, proxy it (including user ID & access token) to my API to authenticate, then continue proxying to notifications iff the user is authorized?
I think the problem really comes down to how do I dynamically set the auth_request URL with the request's user ID and access token. Any help would be greatly appreciated!
Related
A Django site acts as an oauth2 provider. A setup for an app tomcat_app looks like:
Whenever somebody tries to login into tomcat_app a user will get redirected to Django. If the user can provide valid credentials they will get redirected to tomcat_app. So far so good. Tomcat_app further offers a REST API which is aware of the oauth2 workflow. If the reqeust supplies a valid token requests will get accepted.
The knot in my head: A third server should be granted to use the tomcat_app rest api as well. Is it possible to
setup a new user in django externalapp_user/externalapp_password
obtaining a key for tomcat_app by sending the new users credentials to django
Where I'm puzzled is, is how to correctly send the credentials and how to deal with the redirect url. I'm looking for something similar to client type: public and Authorization grant type: Resource ownder password-based
curl -X POST -d "grant_type=password&username=admin&password=admin" http://client:secret#localhost/o/token/
What I understand from the django-oauth-toolkit documentation is that: If you want to use 'Resource owner password-based' Authorization grant type you need to have the user registered on your tomcat_app.
But if you don't want to have the user registered on your app and still provide him with the api endpoint, It is better to use 'Client credentials' Authorization grant type. This will give the third party app the ability to access your api endpoints after they login their users.
You can check out the documentation for better understanding the 'Client credential' flow.
I've developed an website in Flutter that I've deployed on Firebase. What I want to achieve is to redirect the user of an app to this website using an URL that also contains an JWT token because there will be some authenticated requests to be done on the website - but the website doesn't have any login page.
Is it possible to retrieve that token in order to be used in the code of the website?
If you're using Firebase Hosting, all traffic between the client and server goes over an SSL-encrypted connection, so the data can only be seen by the sender and received (unless your certificate chain is compromised).
If you pass the token in the URL, anyone can see it, as the URL is not encrypted. So you'll want to send the token in (for example) a header, such as the pre-defined Authorization header of HTTP. This is actually what the Firebase JavaScript SDKs themselves do to pass authentication information to the Firebase server.s
I have a frontend (SPA, angular2, lite-server) and a hidden backend (not exposed to public, i.e. localhost:8080, spring boot+spring security), frontend can access backend by proxying frontend/api calls to backend/api under the hood.
Basically, the steps for this kind of OAuth2 flow are:
On UI - hit url to authorization server with redirect_uri specified
Authorize
Get back to redirect_uri with access code
???
Server exchanges access code for an authorization token and keeps it
User(authenticated) gets back to the page he was restricted to access
I can't get the steps between 3 and 5. As my backend server is invisible, the redirect_uri should be the one in the frontend. I could possibly use a frontend/api/auth which will proxy the call to backend/api/auth and backend will succesfully get the authorization grant however in this case user won't be redirected back to a frontend. So, should I get the code in the javascript and do a POST to /api/auth from the javascript instead?
Also I don't get how to get back to step 6 after that as after all redirects SPA app will be reloaded(dropping the state) and redirect_uri is an url to /api/auth.
If I get the question right, the easiest would be to "expose" the server via localtunnel or ngrok.
I have an admin-console for an existing service that I want to provide access to by adding login, using our company's OAuth 2.0 service. I want to use Apigee here, so that the web-app with the admin-console does not have to implement the login-logic.
My idea was to use AuthorizationCode flow and let Apigee manage the tokens and I looked into https://github.com/apigee/api-platform-samples/tree/master/sample-proxies/oauth-login-app, but I really can't see how our existing OAuth service fits in.
Is there a sample like that? Perhaps using Google's or Facebook's OAuth service to authenticate the user?
First, Apigee needs to be a proxy into the admin-console. This means that all traffic to the admin-console has to go through Apigee. Otherwise, you won't be able to enforce authentication.
Second, there are a couple different options for integrating with the external oauth 2.0 service. Apigee has the ability to store an external access token and use it as its own, or Apigee can generate a token and store the external access token as a custom attribute.
High level thoughts on how the Apigee proxy could look like:
ProxyEndpoint - endpoint exposed to clients connecting to admin console
TargetEndpoint (not shown in that oauth login-app example) - endpoint for the actual admin console
The flows that execute in the Apigee proxy before sending the request to admin-console will need to implement logic that checks an authentication token. If it's valid, let the request pass onto the TargetEndpoint (admin-console). If the request isn't valid, step through logic that goes calls the external oauth 2.0 server's auth code flow. This will require the following:
Apigee needs to be registered with external oauth 2.0 server.
Logic needs to be built in this proxy to support the redirection based flow of authorization code grant_type (obtaining auth code, receiving the auth code, obtaining token --> all while being redirection based and transparent to user).
In addition to #2, Apigee will need to store the external token as custom attribute and expose the apigee token, or store the external token for verification purposes later on. http://apigee.com/docs/api-services/content/authorize-requests-using-oauth-20 (see Delegating token management). After the token is stored, you'd need to respond with another 302 redirect to the initial uri + token so the request can pass through to admin-console as an authenticated request.
#2 isn't exactly straight-forward and there won't be an example proxy that shows this implementation. If the oauth 2.0 service supported a password grant, it may simplify the implementation, but allows the credentials to pass through apigee and not directly with the authorization server.
I've written my own login app to protect my api following the oauth-login-app example.
I've implemented the web server flow and everything works great.
My question is: how should I handle an authentication failure at step 3? How do I tell he client app that the authentication failed? The user could either press the cancel button, or refuse permission or just enter the wrong details.
When you initiate OAuth 2.0 (dance) with
/authorize
the user-agent land on /login page (created/hosted by you),
post redirect.
enduser(user-agent) submits the username/password
to the page hosted by you. Here you collect the credentials and
submit to Apigee, and if authentication fails, send a HTTP 401
response. Now your application should be in position to re-render
the login page and with a flash "invalid credential".
Now coming to if user is authenticated but rejects the authorization request in
consent page, you should redirect to the "redirect_uri" provided
by client, with error code.
How do I tell he client app that the authentication failed?
The login app will redirect the control back to the application redirect URI - with added error code/description in the URL as hash parameters. In case of success the URL is appended with code or token.
You can do this redirect from your login app directly but I would suggest to make the redirect call first to an Apigee Proxy and let Apigee Proxy send the redirect back to app. Both in case of success and failure. In this way you will have the benefit of using Apigee analytics that helps your understand how many OAuths failed for what reason etc.
EDIT:
You can use the same GenerateAuthorizationCode proxy you have built for the success flow. When login fails or succeeds, in either case you need to pass that information to this proxy. Generally the login app and this proxy should share this information using a common session store. You can not pass this information just using a redirect parameter because that can be changed by the client user agent. When you redirect to the GenerateAuthorizationCode redirect proxy, do so by appending a random session ID in the URL. That id can be used by the GenerateAuthorizationCode proxy to look up the login status from the session store. Then you can either send back a redirect with error or a proper oauth code based on if the login was successful. An easy implementation of the session store can be done using a distributed caching resource in the apigee gateway. Login app can put/get the session using an internal API. While the proxy can use policies to retrieve the session information.