How to get a bearer token to access an API from an MVC application - identityserver3

My user flow is as follows...
User requests a protected resource.
User redirected to authentication provider (e.g. Google)
User redirect back to ASP.Net MVC application which uses cookie authentication.
This works great, and following the MVC sample application from the IdentityServer samples I can see a list of claims for my user.
So the main page of my application is rendered using an MVC view, I have other resources which are authorised via resource authorisation and this works great.
The next part of my application is an API. Let's say it's api.domain.com/stockquote
This should only be useable by authorised users of my application and not publically available.
I have successfully made an Angular JS application with Identity Server and understand that when the token is returned I am able to get the value of /id_token from the URI, store it in localstorage and then use it to form an authorisation header for the API e.g. Authorization=Bearer {token} . Again works nicely.
However, now I am authenticated into my MVC application how do I get this token and put it into local storage so that I can create a header for my API calls?
Can I extract it from the cookie somehow?
Is it a good idea to output it in the HTML stream so that JS can pick it up and put into localstorage (guessing now).
Can I use the token endpoint to somehow get this token?

One way to handle this might be to change the way you authenticate. Instead of handling the callback in MVC on the server side, handle it in JavaScript. Then the token is available for you to store in local storage. This might not be possible if you are making requests on the server side that uses the token as well.

Related

Can a ASP.NET Core MVC web app receive a new Azure AD access token during an Axios Request?

Based on this reading the AuthorizeForScope tag in a controller will handle getting a new access token if there is an issue with the previous access token. This could be if the access token expires or the cache of the server is cleared and and the token was stored in cache similar to the implementations shown in the default Azure AD sample codes on github for calling MS Graph. This does exactly what it should if you are doing full page redirects using the browser URL by accessing a GET controller in my MVC web app. However, if you are using a SPA like VueJS we are not doing full page reloads but instead Axios requests. So if the controller has the AuthorizeForScope tag and the access token was cleared from cache then the tag does what it is suppose to it and creates a redirect for the new challenge to get the new access token. This redirect is returned to Axios as a redirect 302 error. I am able to intercept this event and convert this error to a 401 error and handle it on the front end by pushing the user to a custom login page with a button to do a new challenge manually. However, can this all be done without effecting the flow of the user experience? For example can a new token be obtained without a full page redirect and handled on the web server despite having delegated permissions for my app?
OR is this not possible and since the methods in my controllers do other stuff and not just use this token, should I just run a simple MS Graph function at the beginning of all of my methods in every controller to trip the error early to send that 401 error so they can hit the challenge button and get a new access token with a actual page redirect.

How should my api handle login via auth0?

I'm trying to learn how to utilize auth0 to handle user authentication for an api I am currently creating.
My api has two endpoints:
Login endpoint: /api/login
Request access token endpoint: /api/auth?code={code}
Here the authentication flow is:
User goes to the login endpoint of my api.
User is redirected to auth0 ui.
User inputs their login credentials.
Auth0 redirects back to /api/auth where a request for an access_token is made using the login code.
Firstly, is my understanding the Oauth authentication flow correct? If so, how best should my api handle the initial login redirect to auth0?
Because at the moment when I hit up /api/login from the front-end ui it just returns the html of the login page at auth0. Should I instead return a 302 with the redirect url or is it possible to create an endpoint where the user inputs the username & password via my api and avoids the redirect?
---update---
After a user has authenticated via auth0 they receive a access_token and id_token which should my api use to verify the user is who they say they are?
Not sure if my understanding is correct but I belive that my frontend ui is the OAuth client application and my API service is an OAuth resource server. As such does my api need to call out to auth0 /userinfo to verify the user?
Assuming you are trying to protect an end-user application (your question wasn't clear on that), my understanding is if you are using Auth0, you likely won't need an /api/login and api/auth API. If you are using Auth0 you can get those things during your authentication via Auth0.
I would say your APPLICATION (not API) would redirect the user to the Auth0 login endpoint. You would do that by incorporating the Auth0 SDK of choice, depending on what you're building. For example, if you're building a web app, you may choose to incorporate auth0.js and call webAuth.authorize() to trigger the login. During that login, if you have configured an API within Auth0, and you provide the proper Scope and Audience during your login, your response will return an API token.
Then your user is in a state on the client side where you are logged in, and you have a token. You can then provide that token to your API, and your API can validate that token as needed. Auth0 also has various libraries for token validation (like this spring security one, for example).
Lastly, the question on which oAuth flow to use, that also depends on what type of app you're protecting. There are again Auth0 docs to help. The flow depends on if you're building a server-side web app, a SPA, a native app, etc. Your question was a little confusing, and it sounded a bit like you are building an API and want to protect that. If there is no client-side app (only machine-to-machine API calls), then you wouldn't be dealing with HTML and login pages. You'd likely be getting into the Client Credentials flow, which last I checked was only included for Enterprise Auth0 users.

Confused about callbacks in OAuth flows

Say you have a REST API that you want to protect with an OAuth based authentication system. The regular flow using the website I'm using is:
user clicks a link to login to google
google makes a request to the callback you specified
your application responds to the callback by taking the given tokens and requesting the user data, finding what that user data corresponds to on the database and giving you back a session cookie for the web application and an HTML redirect (for example to the home or whatever you prefer)
Basically the callback endpoint transforms google tokens into your web application session cookies.
Now I'm wondering: how would that work for a mobile application that doesn't know anything about cookies or redirects? It could do:
on google button click, make HTTP request to the google auth URL
google responds with the callback URL you specified
the app makes another request to the above mentioned callback URL to your application
your application returns a cookie session value and a redirect URL to the homepage
the mobile applications forgets about the last redirect URL and takes the cookie session value and uses that for any other requests to the API
Is that right?
One way to do it is that you create an embedded web component on the native mobile UI, you set its URL to the authorization endpoint, the user logs in and authorizes your app, the Authorization Server redirects to your callback URL with an Authorization Token.
Your app subscribes to the changes of the web component, and when it detects the callback URL it takes the Authorization Token, destroy the web component, and calls the REST API to get an Access Token, and then access any protected resources.
Related posts:
Integrate oauth2 with native (iOS/Android) mobile application
Oauth2 flow without redirect_uri
OAuth2 for front end applications
Disclaimer: I never implemented this and I don't work with mobile apps, I just got this from reading stuff.

Facebook, Node & Mobile app - pulling together

I'm trying to build a Facebook-authenticated native mobile app (Windows Phone) that connects to a web service I am creating in Node.
I'd like for a user to:
Log in to Facebook on the mobile app via a native UI or web window
If logged in successfully, create or access server-side user account data tied to that identity
Use the authenticated session to make subsequent authenticated requestsvto that user's data via the native mobile app
My question is: What's the best approach here?
Should I...
Log in the client to facebook locally in the mobile app and pass the Access Token to the node service, and then somehow map the user to my service data based on their facebook account id? That seems grossly insecure if I just pass that token in the URL.
Log the user in via a mobile browser window inside my app, and then redirect back to my Node service in the same window? How do I then make subsequent authenticated requests natively in my app?
Do something else entirely?
Sorry this is so open ended but this is the first time I have tied these things together and although there's a lot of info on each part I've yet to find something that describes the overall pattern / best practice for this design.
Your question is quite opinion based...but still I will try to help.
First of all, you can pass access token in url, its not insecure if you use https. Even if logged into facebook from your mobile app, than also its going to pass a access token in url only. If you mean having the token in http://something.com/access_token, than its not how its should be done.
If you look into the Oauth 2.0 draft you will understand that its done through setting a header Authorization with the value being the token and token_type. Take a good look at the draft.
As your solution I think its fine if you just use the first method mentioned in the question by sending the access token in header as I mentioned in your app and in turn authenticating that token from facebook on each request.
If you think this is just too long a flow for authenticating every request from facebook, than you can get access token by sending request from your mobile app to server and let the server handle the access token and store it in database which you can authenticate each request.
In any case take a look at Passport module, it has facebook and other auth built-in and should be sufficient for your needs.

How to authenticate iOS/iPhone users with remote web application and re-use authentication ticket in future requests to the same web application?

I am building an iOS application and I need to be able to make authenticated requests to a Rails 3 application for various bits of data. The Rails 3 application is using omniauth and URLs like https://myapp.com/auth/facebook to, for example, authenticate users via facebook ... and once authenticated, stores the authentication in a secured cookie named "auth.""
What I want to know is how to authenticate my users from the iOS/iPhone application, persist the authentication token and send it along with future requests to the Rails application?
Using ASIHTTPRequest I'm thinking of doing something like this:
Open a UIWebview, loading with a URL from my web application specific for the provider they want to authenticate with (e.g. myapp.com/auth/facebook for facebook or myapp.com/auth/yahoo for yahoo, etc....).
On success, somehow parse out and store the authentication cookie in the iOS application without displaying the webpage folks usually see when authenticating via the website ... and instead closing the UIWebView and navigating back to another UIVewController in the iOS application.
Somehow include the persisted authentication token with future web requests to the Rails application.
I also want to allow users to allow the iOS application to store this information locally so they don't have to re-login to the remote application if they choose too.
Is this approach appropriate? Is there a better way? And of course, how to actually implement the above?
Thanks - wg
Using OAuth is pretty easy (well, easy is not the word...), but I made an iOS application and a java server that use OAUth as identity schema and, following the full cycle, finally I adquired a token that identifies this user and (as only can be accessed using signed requests) can be safely stored in the phone (I use just the standardUserDefaults to store it). Only your application (using the secret) can sign the requests.
I don't know if this serves to you...
Ah! After the identification via web, the browser redirect a special url (registered for my application) and the url opens my application including the token in its parameters, so it is easy to retrieve the token after the identification phase in handleOpenURL.
Once the UIWebview has authenticated with said service, get it to load another URL (for example: through a javascript on the page which said service returns to after authentication).
Capture this request using a UIWebViewDelegate object which implements the following protocol method:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
From here you have the NSURLRequest object. You can extract the headers of the request to NSDictionary which will contain the authentication cookie details, token, etc. using the following method of NSURLRequest
- (NSDictionary *)allHTTPHeaderFields
For my app this is what I'm doing.
My app is using devise with omniauth for login and user stuff.
Devise by itself can generate a unique token, with the flag token_authenticatable.
So on my login request, if the login is successful I reply with a JSON representation of my user and my user token. I save all that on the phone memory.
Then on every request I add the param auth_token=MY_USER_TOKEN.
And that's about it.
I had just a problem with the Facebook auth, because I'm using the Ios facebook SDK, so I forward the FB token to my app, verify it, and then just return the same devise auth_token for all following requests.
Ok here we go, I dont know the exact setup of your web service and all that, but what you can do is store the authentication token on the device using SQLite or Core Data, I am currently working on a app that requires authentication, and what I do is store the username and password locally on the device in the SQLite db using Core Data to interact with the db, then whenever I make an API calls I use the stored username and password for the authentication on the server side using gets, but I believe it is saver using post, as long as the web server has great security I don't believe there is any security risks. In what I understand about what you are building I would authenticate the user say on first launch and have the user be able to change log in credentials at a later stage, but after authentication I would send back an authentication token to the device and store that in the db and then whenever I need to authenticate with the web service I would send the auth token with a post request to the server. Does this make sense?