Use identity server 3 to exchange a facebook token for my application token - identityserver3

I'm investigating how to use id server to provide auth services for a native mobile app that will talk to a Web API that we are developing. I started off with the flow as described in the MVC walkthrough - so the user is redirected by ID Server to FB (with acr_value/idp) and then redirected back after sign-in, where I can do the claims transformation and issue a token for our application.
The developers of the native client have concerns about this though, and would rather use the FB sdk to log the user in to FB, instead of having id server issue the token after redirections. The following issue on the previous version of ID server explains this well:
https://github.com/IdentityServer/IdentityServer2/issues/503
How would I go about doing this with id server 3?

This is a perfect use case for a custom grant.
1) first do native FB login
2) send FB token to IdentityServer token endpoint using custom grant
3) write a custom grant validator that validates the FB token
4) return JWT token for your APIs
Documentation:
https://identityserver.github.io/Documentation/docsv2/advanced/customGrantTypes.html

Related

ASP.Net Core Web API Authentication with Facebook

I have a Web API developed with ASP.Net Core. I also have a client app developed with Next.js and it uses NextAuth.js to handle the authentication.
In the UI, when a user is authenticated, I have access to the access token from Facebook.
My question is how can I use this access token to authenticate the requests sent to the back-end API.
This is the back-end code used to register the Facebook authentication scheme (it is all standard):
builder.Services.AddAuthentication()
.AddFacebook(
facebookOptions =>
{
facebookOptions.AppId = "<my_app_id>";
facebookOptions.AppSecret = "<my_app_secret>";
});
I want to construct a Postman request that can authenticate my user using a specific access token but I do not know where to put this access token and whether this is possible at all.
Just sending the request like this (without any modifications) results in visualizing the Facebook login page.
Your Asp.NetCore project integrates Facebook login. After logging in, the token you get can only access protected resources in the current project, such as: [Authorize].
If you want to access Facebook's resources, you need to write your own code to get the token and then access the resources.
1. How to Get Facebook Access Token in a couple of minutes: 2020 guide
2. How to get current user access token from Facebook SDK in C#? Not the App access token
After you get facebook access_token, then you can access Facebook's resources.

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.

How to implement external login to identity backend from Xamarin

I have a website using ASP.NET Core, which uses MS Identity and external login from Facebook.
I have a Xamarin app that logs to this backend via login/password using Xamarin.Auth. I am wondering which is the best way to allow external login to Facebook from the app?
Should I create a separate Facebook app for Android or should I use the same as the website?
What would be the flow?
I am thinking of something like:
Using the Facebook sdk to log in
Pass the token to the server
Check from server side if the email exists or the FB user id exists
If yes check whether the app is registered using Facebook and if yes login
If no create an account
But until now I haven't stored the user's Facebook Id (only the email, that the user can also modify).
Xamarin.Auth is client library and currently has no server side implementations.
So, your server is Protected Resource and Facebook will be Authorisation Server. After you obtain your tokens (access_token and refresh_token) you would try to access Protected Resource presenting access_token as a credential. Protected Resource will perform token introspection (this could be separate service-server) which will decode the token, lookup username (mail) and check expiration of the token.
This is not specified in draft (RFC) so check how FB does token introspection.
Few links for more info:
How to validate an OAuth 2.0 access token for a resource server?
http://blog.api-security.org/2014/10/oauth-20-token-introspection-profile.html
https://www.quora.com/In-OAuth-2-0-how-do-resource-servers-assert-a-token-issued-by-an-authorization-server
https://connect2id.com/products/server/docs/api/token-introspection
https://leastprivilege.com/2015/12/27/oauth-2-0-token-introspection-middleware-for-asp-net-5/

How to use Facebook OAuth with Ember Simple Auth?

I have an Ember.js app using Ember Simple Auth. The API returns an auth token on successful sign in with email and password. I'm trying to add Facebook Login using their Javascript SDK. Upon successful sign in with Facebook, I would like to post the Facebook access token back to our API, so that the API can store the access token and respond with our own auth token. However, I'm not sure how to connect this to Ember Simple Auth so that the auth token can be stored outside of the normal email/password sign in. What do I need to do in order to make this work?
The dummy app in the repository implements the exact functionality you're describing (except it uses torii instead of the Facebook JS SDK). If you're using Rails on the server you might find the RailsApiAuth engine helpful that already implements the server part for the Facebook auth code flow.

REST API for website which uses Facebook for authentication

We have a website where the only way to login and authenticate yourself with the site is with Facebook (this was not my choice). The first time you login with Facebook, an account gets automatically created for you.
We now want to create an iPhone application for our site and also a public API for others to use our service.
This question is about how to authenticate with our website from the app/API and is broken into 2 parts:
What is the correct way to handle REST authentication from an API to a website which only uses Facebook OAuth as an authentication method?
I have read and researched a lot about standard methods of authentication for REST API. We can't use such methods as Basic Auth over HTTPS, as there are no credentials for a user as such. Something like this seems to be only for authenticating applications using the API.
Currently, the best way I can think is you hit an /authorize end-point on our API, it redirects to Facebook OAuth, then redirects back to the site and provides a 'token' which the user of the API can use to authenticate subsequent requests.
For an official application that we create, we wouldn't necessarily need to use the public API in the same way. What would be the best way then to talk to our website and authenticate users?
I understand (I think) how to authenticate 3rd-party applications that are using our API, using API (public) keys and secret (private) keys. However, when it comes to authenticating the user who is using the app, I am getting rather confused about how to go about it when the only way we have to authenticate a user is Facebook.
I feel like I'm missing something very obvious, or don't fully understand how public REST APIs should work, so any advice and help would be greatly appreciated.
UPDATE: see below
I've been thinking hard about this question too. It's not entirely clear to me yet but here's the route I am thinking of going. I am creating a REST API an my users only auth with Facebook connect.
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
In every call to my custom API I'll include the Facebook user id and the access token.
On the API (for every method that requires user authentication):
Make a request to the /me Facebook graph using the access token from above.
Verify that the Facebook user id returned matches the user id passed to my API from above.
If the access token has expired additional communication is required.
I have yet to test this. How does it sound?
--- Update: July 27th, 2014 to answer question ---
I only use the above exchange once upon login. Once I determine which user is logging in, I create my own access token, and that token is used from that point going forward. So the new flow looks like this...
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
Request an access token from my API, including the Facebook token as a parameter
On the API
Receive access token request.
Make a request to the /me Facebook graph using the facebook access token
Verify that the Facebook user exists and match to a user in my database
Create my own access token, save it and return it to the client to be used from this point forward
This is my implementation using JWTs (JSON Web Tokens), basically similar to Chris' updated answer. I have used Facebook JS SDK and JWT.
Here's my implementation.
Client: Use Facebook JS SDK to log in and get the access token.
Client: Request JWT from my API by calling /verify-access-token endpoint.
MyAPI: Receives access token, verify it by calling /me endpoint of Facebook API.
MyAPI: If access token is valid, finds the user from database, logs in the user if exist. Create a JWT with required fields as payload, set an expiry, sign with the secret key and send back to the client.
Client: Stores the JWT in local storage.
Client: Sends the token (the JWT from step 5) along with the request for the next API call.
MyAPI: validate the token with the secret key, if token is valid, exchange the token for a new one, send it back to the client along with the API response. (No external API calls for verification of the token here after) [if the token is invalid/expired request client to authenticate again and repeat from 1]
Client Replaces the stored token with the new one and use it for the next API call. Once the token expiry is met, the token expires revoking access to API.
Every token is used once.
Read more answers about security and JWT
How secure is JWT
If you can decode JWT how are they secure?
JSON Web Tokens (JWT) as user identification and authentication tokens
I am trying to answer the same question and have been going through a lot of reading recently...
I won't have "the" answer but things are getting a little clearer for me. Have you read the comments in the article you mentioned? I found them really interesting and helpful.
As a result, and in the light of how things have evolved since the first article has been written, here's what I think I'll do:
HTTPS everywhere — this allows you to forget about HMAC, signing, nonce, ...
Use OAuth2:
When authentication requests come from my own apps/website, use this 'trick' (or a variation of it) described in a reply to the article mentioned before.
In my case, I have two types of users: those with classic login/password credentials and those who have signed up with Facebook Connect.
So I'd provide a regular login form with a "Login with Facebook" button. If the user logs in with his "classic" credentials, I'd just send these to my OAuth2 endpoint with a grant_type=password.
If he chooses to log in via Facebook, I think that would be a two-steps process:
First, use Facebook iOS SDK to open an FBSession
When that's done and the app is given back control, there should be a way to get a Facebook ID for that user. I'd send this ID alone to my OAuth2 endpoint with an extension grant understood by my server as "using an FB User ID".
Please note that I am still heavily researching on all this stuff, so that might not be a perfect answer... maybe not even a correct one! But I think that would make for a good starting point.
The idea of using an "extension grant" for the Facebook authentication might involve having to register it to do things properly? I'm not quite sure.
Anyway, I hope I was able to help you even a bit, and that at least it can start a discussion to find the best solution to this problem :)
Update
The Facebook login is not a solution as pointed in the comments: anybody could send an arbitrary user ID and log in as this user on the API.
What about doing it like this:
Show a login form with a "Facebook login" button
If this login method is chosen, act kinda like the Facebook SDK: open a web page from your authentication server, which will initiate the Facebook login.
Once the user has logged in, Facebook will use your redirect URL to confirm; make that URL point to another endpoint of your authentication server (possibly with an extra parameter indicating the call came from an app?)
When the authentication endpoint is hit, the authentication can securely identify the user, retain its FB User ID/FB Session and return an access token to your app using a custom URL scheme, just like the Facebook SDK would do
Looks better?