How to use google authencticaion in asp.net core web app and web api that uses JWT - rest

I am working on a Web Application in asp.net core 2.2. Web API serves every request coming from Web Application. I am using JWT Token Authentication in Web API. That token goes in every request from web application.
Web APP -----> Web API ----> Data Layer----> EF Core ---->DB
In the login, the user enters email and password on the web interface and hit on login button. The request goes to Web API than to DB passing from all other layers. If the user is valid then in Web API a token is generated and pass it in the response to Web App. Now, in every further request from Web App to Web API, Web-APP sends this token in the header.
Now, I want to add an external authentication provider like Google. Problem is that I am not sure how to handle the flow of my application? Because Google Authentication is just for web application and not affects the functionality of Web API.
Any suggestion?

What you need to do is to delegate user authentication to an external Identity Provider (IdP). In the login screen, you would typically allow users to choose between using email/password or external IdP (e.g. Google, Facebook, etc ...). If a user choose the latter, the "identity verification" step will be taken care by the IdP and then HTTP redirected to you (to a URL that you define) along with an ID token that is digitally signed and contains some user's information (name, email, ...)
The change to the application flow in that case would be as follow:
Web APP -----> Web API ----> Data Layer----> EF Core ---->DB
| ^
v |
Identity Provider (e.g. Google)
Note that the redirection to and from the IdP are generally based on HTTP redirect. In the simple nominal case, you don't need to call the IdP from the Web API layer, although you must define each supported one as a trusted issuer of ID Tokens (required for signature verification)
Step-by-step instructions are generally provided by the IdP, r.f. Google Sign-In and Facebook login

I would suggest you use Identity server 4 as your identity provider .
Your web api will be a resource which protected by Identity server . In your client app, when starting the authentication process , according to authentication flow , user will be redirected to identity server for authentication , user could choose local db user login or external login via Google authentication . If user choose local db , user will enter his credential on identity server's login page and validate the credential in your local db. if credential is correct , then identity server will issue a token and redirect back with token to client app . If user choose external login , user will be redirect to Google's login page for sign in , identity server will issue token after redirecting from Google(get claims from token issued by Google) and redirect back with token to client app .
During the authentication flow , client could set which api resource he want to access , after user consent the permission for accessing the api resource(your web api ) , the issued access token could be used to access your web api .
Identity Server document : http://docs.identityserver.io/en/latest
& Code samples .

Related

How to perform user registration and authentication between a single page application and a REST API with OpenID Connect

Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.

Identity Server Resource Owner flow with external Identity Provider

We have a project where the client requests the use of their own Identity Provider, in this case, it is SalesForce.
We secure the application using IdentityServer 3 and have configured it that for this client (based on parameters) it will use SalesForce as the IDP.
For the web app, no problem, Identity Server redirects to the Sales Force login page and everything works great.
Now we have a mobile app to build and the client would like to avoid having a web login page and would rather have a nice polished login form built in the application. This means that we will have to use the Resource Owner flow.
Now, the users creds are on SalesForce side so how does that work and is this at all possible in IdentityServer 3 ?
I see 2 possibilities but I kind of like neither of them:
Send the auth call to IdentityServer which should detect that it is up to SalesForce to validate the user and forwards the request there. I think it is not good as I would rather avoid having my IdentityServer dealing with credentials that he should not even know
Send a first auth call to SalesForce to get some "id token" that would then allow me to send another auth call to IdentityServer which will then recognize the "id token" and release an access token.
That seems like a stretch and forces the app to know that there is an IDP which is none of its business.
Any idea?

Understanding OAuth2 flow

I'm developing an Android app that consumes a REST service that uses OAuth protocol. In the first activity, app shows a login screen. This is the flow:
1) User puts her username and password.
2) App makes a request to REST service, providing username and password.
3) REST service check the credentials and if are correct, ask for an access_token to my OAuth2 provider server.
4) REST service answers to the app providing the access_token and the refresh_token
5) In the next requests to the REST server (to get data like people, articles...) app will provide the access_token and the refresh_token.
6) When REST service process a request, will validate the access_token (using an token info endpoint of my OAuth server).
7) If the access_token is correct and has not expired, REST service will return the data that the app were asking for.
When REST service detects that access_token has expired, asks for another with using the refresh_roken.
Now, my questions:
When REST service retrieve a new access_token after the old one expires, has the REST service send it to the app in that response?
If so, has the app check, in each request/response, if new a new access_token has been sent from the REST service?
I don't know if I'm in the right way, I'm trying to understand the flow.
Thanks.
Assuming there's no browser involved and the app (aka. Client) uses what is called the Resource Owner Password Credentials grant, the flow is:
the User (aka. Resource Owner) provides his/her username and password to the Client
the Client makes a Token Request to the Authorization Server, providing username and password
the Authorization Server checks the credentials and if they are correct, it provides an access token and optionally a refresh token to the Client in the response
in the requests to the REST server (to get data like people, articles...) the Client will provide the access token
when the REST service process a request, it will validate the access token calling the token validation endpoint of the Authorization Server or by validating the token locally (e.g. if the access token is a JWT).
if the access token is correct, has not expired and has the right permissions (aka. "scopes"), the REST service will return the data that the Client was asking for
when the Client detects that access_token has expired (e.g. because the REST server returns an error), it asks the Authorization Server for another access token using the refresh token using the so-called Refresh Token grant/flow
OAuth 2.0 flows:
An application registers with the auth provider e.g. Facebook, Google, etc with app name, website and callback/postback URL
The application receives the client id and secret from the auth provider
The application user accesses the auth provider for authentication and user approves the resource permissions
The auth provider returns the auth token with respect to the user permissions to the application
The application accesses the resource provider using the auth tokens
The resource provider returns the protected resources after validating the auth tokens to the application
Do comment if you need more understanding!

Grails & Spring Security & Facebook & Oauth2 - Restfull server

What would be the actual solution to build a server with Grails and Spring Security that meets the following requirements :
Access to the server would be restfull, so only by third party clients (mobile,...)
The authentication would use the oauth2 facebook services and the client would use a facebook SDK to provide a token to the server
The authentication would be on per request basis so the token would be passed on the request as GET parameter (not POST as the Rest API uses it)
No need to access Facebook user's information, only authentication
I tried Spring Security Facebook but the Json filter only returns user details so no per request or per session authentication.
I noticed Spring Security Oauth2 Provider but to me it's a provider and not a consumer that could plug into another provider like Facebook so no clue on how to use it.
Spring Social doesn't seem to meet my requirements.
As a result of this search for information, I intend to write a plugin to create a Restfull server connected to facebook.
Thanks in advance
You could implement a security filter on the top of all your requests, and then if the request contains an auth header for the API you respond with as a restful API, otherwise you redirect your users to the login page, handled by the oauth authentication service, where you let the users login with the oath method (facebook, mozilla persona or whatever you like)

Custom STS SSO with redirection to another web site in a different domain

All,
I am working on a SSO Project using WIF for my current employer .Registered users can log in to a portal that is public facing and receive access to a suite of applications . My employer has purchased a COTS Application(Claims Aware) hosted in another city . What they would like to do is the following
1a)Have Registered users log into the Portal located at portal.domain1.com
1b)During the login process , the portal communicates with an STS in the background which returns a signed and encrypted token back to the browser
2)User sees a link to the COTS Product on the Portal Page and clicks on it
3)They are redirected to app.domain2.com
4)App.domain2.com does not need to autenticate the user again since they receive the identity token from the portal .The user is able to establish a session from his browser with app.domain2.com
5)The browser is able to persist the token across all requests to the domain2 server
We will not be doing ADFS 2.0 but a Custom STS . My question is , is there a way to do it in SAML ?
Thanks,
Raja
You can push SAML authentication statements.
When the link is clicked on portal.domain1.com you use javascript to post a saml statement to app.domain2.com.