ASP.NET Web API to issue cookie for SPA on different domain - angularjs

My AngularJS SPA and its ASP.NET WebAPI 2 API are located on different domains. SPA user is authorized in API by obtaining JWT token from API auth server and then SPA sends each request with Authorization Bearer request header containing this token to access protected API endpoints.
Now we need to expose some API endpoints to be directly accessible by users when they are logged in to SPA. But I'm not sure how to implement it because we don't use cookies and our API is located on different domain than our SPA.
Is it possible to configure ASP.NET WebAPI 2 to issue cookie to a different domain (API domain) when POST request with credentials is sent from SPA from another domain?

Consider that cookie is being stored in client-side not in your server-side. You can add some tracker (i.e Google Analytics, or create your own tracker) to store the log data from users based on their tokens or their server variables like ip address, session key and so on. Notice that tracker service will be launched on server-side and the tracker on the client-side like trackers javascript snippet-codes.
Hope this can be helpfull. Regards.

Related

React SSO using SAML without web server

I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.

How to use google authentication for an angular web app and a .net web api hosted on azure

I have an angular web app talking to a c# .net web api back end.
They are both hosted on azure app services.
Azure app services offers a suite of authentication services and I've chosen to use google auth.
I've got my google client id and secret setup in azure google auth and my web app correctly shows and prompts me for my google credentials.
My problem now, is that i need my web api back end to authenticate the web app google token. I couldn't find any articles or tutorials that demonstrates the following:
How to get and send the token to the web api? I've read that azure app service should automatically inject the necessary auth headers but any calls to my api do not include those headers. Should i manually call auth/me and add them to the request header?
How do i get my web api to authenticate the details from the request header with google auth? Do i need a separate client id for the web api or should i re-use the web app client id?
Cheers!
According to your description, I assumed that you are using the built-in Authentication / Authorization provided by Azure App Service.
AFAIK, App Service Authentication (Easy Auth) provides two flows: client-managed and server-managed flow. For the server-managed flow, the server code manages the sign-in process for you, and your backend would directly receive the token from the relevant identity provider (e.g. Google, AAD,etc.), then both generate a authenticationToken for browser-less apps and AppServiceAuthSession cookie for browser apps. Details you could follow Authentication flow.
For your angular web app, you could just use server-managed flow, after user successfully logged, you need to call https://<your-angular-app-name>.azurewebsites.net/.auth/me to retrieve the google access_token, then send the following request against your web api endpoint for retrieving the authenticationToken as follows:
POST https://<your-webapi-app-name>.azurewebsites.net/.auth/login/google
Body {"access_token":"<the-google-access-token>"}
After successfully retrieved the authenticationToken from your Web API endpoint, you could send the following subsequent requests for accessing your APIs:
GET https://<your-webapi-app-name>.azurewebsites.net/api/values
Header x-zumo-auth:"<authenticationToken-generated-by-your-webapi>"
Moreover, you could also use client-managed flow in your angular web app, you may need to directly contact with your identity provider (Google) to retrieve the access_token in your client via Auth0 or google-signin or other third-party libraries. Then you may need to both send request to your angular web app and Web API web app for retrieving the authenticationToken as the above request sample.
Do i need a separate client id for the web api or should i re-use the web app client id?
Per my understanding, you must use the same google application. For AAD authentication, you could configure a AAD app with the access permissions to another AAD app.

Problems combining JWT Bearer Authenticating Web API with Asp.Net Core 2.0

I have the following setup:
Web API with JWT Bearer Auth
Asp.Net Core 2.0 MVC handling identities and providing views
AngularJS - client
Angular is requesting JWT token and passing it on subsequents http requests.
AJAX calls are working fine. The problem is if I request an MVC action with [Authorize] through my browser, that token is obviously not validated, because there is no cookie and no auth header.
How would I go about implementing signin functionality to non-ajax requests?
I assume I need to implement some sort of Cookie Authentication, but I was hoping to avoid it after moving to JWT.
I know this could probably be solved by migrating to SPA, but I was wondering if there was a way to keep todays solution with MVC serving views - old habit :(
If you want server-side JWT authentication, then you need to store your JWT in a cookie instead of local storage. Cookies are issued for your site's domain, so when you request youre MVC app for a view and assuming your API and your MVC site have the same origin (same schema + host + port), there should be no problem for protected MVC controller to process incoming cookie in HTTP(S) request and make a decision on how to respond. WebAPI should also be able to handle cookies with JWT payload. I found nice article with sample project about ASP.NET Core MVC Authentication here: https://auth0.com/blog/asp-dot-net-core-authentication-tutorial/
For your AngularJS SPA it shouldn't be a problem to set JWT to a cookie instead of putting it to local storage. It would be actually more secure way to store JWT, but you need to make sure your JWT won't get too long, because cookie payload size is limited. More about it here: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

How can multiple services re-use the authentication cookie?

I want to understand how a static site with no backend can use okta with other custom API services hosted on other platforms.
Scenerio:
Website is a angluar/reactjs that is hosted as a "static" website.
I'm assuming when you authenticate using okta in e.g. react/angular website I am able to store the okta session id in local storage or cookie.
How say I create a web service and host that on heroku, how can I figure out if the user has authenticated or not and re-use the session?
The scenario where you have:
A JavaScript frontend application, hosted statically
A backend web service (API), that the JavaScript app makes API requests to
is a classic single-page app (SPA) scenario. The recommended authentication flow is the OpenID Connect implicit flow.
In plain English, you are:
Setting up your JavaScript app to talk to Okta (or another OpenID Connect identity provider)
Getting an access token from the identity provider
Attaching the access token to an API request to authorize it
Your API service could be running on Heroku, or somewhere else. In your API service code, you have to validate the access token before you decide to accept the request. The API service can go back and talk to the identity provider to determine if the user's access token is still valid.
How the API service validates the token depends on what language you are using to build your API service. But, that's basic idea: the access token is what authorizes the user's requests.

AngularJs + Rest Backend CSRF Security

I am building a simple AngularJs web app that hits a REST Api built with Flask. From what I understand, there are a few ways to protect against CSRF, one of which is sending back a CSRF token when the user authenticates.
If I wanted to make my API available to both the Web Application and to users who want to use it as an API for development, would I need 2 endpoints for each endpoint that allows POST requests [one for the app that requires CSRF token + auth token and one for the developers that requires just an api access key]?
Not necessarily. Broadly, you have two options:
Proxy the REST API through whatever server-side container your web app is running in. Your web-app proxy can then implement the CSRF protection and insert the API-key into the API request.
Check the referrer header on all API requests. Although this requires that your Angular SPA and API share the same authentication mechanism, so you'd have to use something more sophisticated than an API key, like OAuth.

Resources