Sharing access token from .NET MVC app to embedded react app - reactjs

We have the following applications
a) We have ASP.NET MVC 4 application.
b) We have react application embedded inside ASP.NET MVC page (in the razor view)
c) We have .NET Core API application that has bunch of services secured
Now we needed the embedded react app to get the access token. Here are options:
have .NET MVC app create access token in cookie for react app to pick up and use.
have react app call a service GetAccessToken on .NET MVC app to get access token and use it as bearer token for calling APIs.
have all the react .NET Core API calls proxied through ASP.NET MVC app (no need to share access token to react app, but increases load on .NET MVC app)
have react integrate with IDP, .NET MVC app integrate with IDP separately and both get their own access tokens and use them to call protected APIs (there would be issues with double redirections once for .NET MVC login, and second for react app login and handling of redirecting to target page post login)
Can you please share your thoughts and which approach do you see as good and least vulnerable from security standpoint and why the other options not suitable? is #1 or #2 good enough solution security wise that you do not have to do #3, or #4

Related

MSAL authentication and authorization from React to Web API

I have some trouble understanding the MSAL authentication and authorization. I have a single page app developed in React. I have setup the MSAL Azure SSO authentication by registering the web app on the Azure AD. Now, I have a Web API (in .Net Core) which is running on a separate app service. How do I integrate the authentication from my React app to the Web API?
Few questions coming to mind:
Do I have to register the Web API app as well similar to my React app?
Do I have to pass the auth token from my React App to the Web API?
Do I have to setup the authentication only on the Web API side (using MSAL.Net) and the React App will connect to it?
Please share your thoughts. Let me know if I can explain any better.
If you are the author of both react app and web API, you can register just one app and use ClientId for both.
Yes. If your react app is standalone app (not a part of Asp.net app) you can use msal.js to login with AzureAD and then use openId token to login to your web API. Also you can use access token to access services secured by Azure (e.g. Microsoft Graph) directly from React.
If your React app is a part of Asp.net app, you can setup Auth on server. If it's standalone app you need to use approach from 2.
If your React app is standalone app and if you are going to access "downstream" API (like Microsoft Graph) from Web API, you need to implement On-Behalf-Of mechanism on your Web API. In two words:
- user login with React app and access Web API with openId token;
- Web API acquires new access token based on token sent from client
- Web API access Microsoft Graph with this new access token.
You can find Server side example here.
Client side example from another answer works in this case, but you need to send row openId to Web API instead on access token.
P.S. You can use access token instead of idToken to access your WebAPI as well, but in this case you need to define separate scope for your WebAPI in Azure as well. After that you can use this scope to access your WebAPI and separate set of scopes to access MS Graph.
Here is a complete video tutorial and source code on how to use MSAL with React to call Microsoft Graph.
The only different in your case will be that instead of calling Microsoft Graph, you will call your own API.
Bottomline is - there is no direct integration package yet for react. Which can also be read from the official statement on the msal-js repo:
After our current libraries are up to standards, we will begin
balancing new feature requests, with new platforms such as react and
node.js.
See Here. It allows you to call Graph API from client side.

Security and OpenId Connect Flows with ASP.Net Core 2.1 and React

I'm currently in the process of implementing security on my ASP.Net Core 2.1 React/Redux app and I've been following the Js Client quickstart as well as the other Identity Server quickstarts. I've also been reading up on the concepts mentioned in Identity Server 4 + Identity Framework + React Front End and following the pluralsight course Securing ASP.NET Core 2 with OAuth2 and OpenID Connect which goes into oidc in the context of IDS4 a bit deeper.
During this pluralsight course the author goes into OpenId Connect flows (here if you have access) and from what I gather I'll need to use the Hybrid flow for Confidential clients and long-lived access through refresh tokens due to roject requirements but the author discusses potential security flaws this would introduce on the client-side. The reason being I would require a clientsecret, and a JavaScript app can't safely store one as it's a public client.
So here's my confusion, my client side app is built using VS2017's project template for creating an ASP.Net Core app with React and Redux - so is it still a Javascript App? This Web App will login through a single Identity Management Source (IDS4) and will need to grant the client access to the web project (React +.NET Core) as well as the WebApi (through controllers on the web project), so is there a way to SECURELY use the Hybrid flow to achieve this?
NOTE - the index page rendered by the ASP.NET side of the client is an html file, would it be more secure if this were rendered as .cshtml with security on this root page? What's the best practice here for security?
The recommendation for a pure JavaScript app is to use implicit flow which is what the oidc-client-js library supports. It’s the best fit for that architecture and supports automatic access token renewal but it’s not completely without its downsides - specifically being vulnerable to token theft via XSS.
You could use a server side hybrid flow combined with a cookie for backend auth but then you’d have to mitigate against CSRF.

Use IdentiyServer or not for external login provider only web application with asp.net core

I am building a web application with
Asp.net Core 2.0 Web API
AngularJS 4+
SQL Server
User signup/login only through Google/Facebook/LinkedIn. I will save user info like name and email I receive from them into SQL db table. I do not have a plan to offer manual registration on my website with email and password. I do not want to maintain user credentials, forget the password, securing user passwords and all nitty-gritty around that.
As of now, there is no plan to build a mobile app. I am learning .Net Core and stumble upon IdentityServer4 as a recommended way to provide identity in asp.net core applications. I went through all docs, example and tried out few sample application. I think I am clear how configuration and workflow of identityserver.
My questions are
Is it worth employing IdentityServer4 in my architecture since my identity is external provider only? I was thinking about using default Asp.net Identity with.AddCookie(), .AddGoogle() and .AddJwtBearer() to retrieve the cookie from Google/Facebook/LinkedIn, use AddGoogle AddFacebook AddLinkedIn middleware to handle callback, extract claimprincipal and set Jwt token for Angular JS app to use in its XMLHttp request.
What benefits do I get outsourcing this work to IdentityServer4 besides identity in one place best practice?
I appreciate your tiny or big feedback on this.
IdentityServer is great for handling many clients that access many protected resources. You seem to have one client (the so called AngularJS 4+ app) and one resource, the Asp.net Core 2.0 Web API.
A point of clarity is that you have no need for ASP.NET Identity and all those middlewares for Google, LinkedIn, etc. If your client is truly an Angular javascript application, then it does not need a server side component like ASP.NET Core- it is simply a browser application. You can use a javascript library like oidc-client and configure your external authentication providers according to their own needs. You will receive an id_token and/or access_token to store in browser and utlimately pass to your Api Resource.
Speaking of your Api Resource, this application can validate directly with the token issuer, be it Google or Facebook or whoever.
So with this setup: (a) a browser app (Angular), (b) a server WebApi (ASP.NET CORE), and (c) and an identity/access control service (Google, Facebook, etc.) you certainly do not need any additional applications that run ASP.NET Identity or IdentityServer4. Seems like it would be easier without them.
If your Angular app is actually in an ASP.NET MVC, then the same is true.
If your Angular app and your WebApi are all part on one ASP.NET project then the same is true and all you need is an identity provider to return an id_token.

Where is Login on App using Identity Server 4?

On an ASP.NET Core project with EF Core and ASP Identity I have 3 applications:
Web API
It will be accessed by the Angular 2 application.
In the future it will also be accessed by mobile applications.
ASP.NET MVC as a container for an Angular 2 application.
ASP.NET Core Auth with Identity Server 4.
I have a few questions about using Identity Server 4:
The Auth application should be Console or ASP.NET MVC?
Where is the Login page?
Centralized in Auth application so Auth would be ASP.NET MVC / Angular 2?
Or a login in the Web Application and one in the Mobile Application?
In case the login page is centralized in Auth application as MVC/Angular2:
3.1. In the login page I might need to display a phrase from the database.
So the Auth application can call the API in that case?
3.2. How does the Auth application verify the username and password?
Does it access the API to verify it or access directly the database?
1) Not sure what you mean by "Auth application" but IdentityServer4 is middleware for ASPNET Core. So it will be your central authority for issuing tokens for authorization.
2) The login page would be hosted within The IdentityServer4 ASPNET Core application as a normal web page powered by MVC and Razor. There is a repository with examples here.
3.1)
You can do a database call and hydrate the view model with this message when a user gets directed to the login page and access that view model using normal MVC/razor patterns.
3.2)
This is up to you, you may inject a repository or store that verifies users and their passwords in the controller or some other service.
If you follow the sample many things will become much clearer. If anything is still confusing let me know.

How to use the same Identity in ASP.NET Web API and MVC?

I have the following scenario:
MVC App - ASP.NET MVC application that has Identity installed in it.
SPA App - Angular SPA app that is located in an area inside the MVC App.
Web API - ASP.NET Web API service that is used by the SPA App.
Both, MVC App and Web API should use the same user accounts. So, now, I have the Identity installed in the MVC App. There would be a View in it that will load the SPA App and the SPA App is going to make requests to the Web API. But the Web API will work only if the user is authenticated, thus it needs a Bearer Token sent by the client. So, when the user gets authenticated in the MVC App and opens the View with the SPA App, I should somehow get a Token for the same user that is authenticated in the MVC App, place it in the SPA App, and send the token from the SPA App JavaScript to the Web API.
Is this possible? Or is there a better way to do it?
Here is what you can do , Create a new class library project . Move all identity component from your mvc project to that library. reference that project to web api project and mvc project .
i have done in couple of project where i need api and mvc . it works for me. Try this it will definitely work. let me know if you din't understand correctly
It is not a real answer to your question but if you use Asp.net MVC only for bootstrapping your single page application then you may have the option to use only web api authentication. After your spa is bootstrapped then you can check if you have an authenticated user and get user specific info to customize the page for your user.
In that scenario you do not need to use Asp.net MVC authentication but sometimes you may need to use Asp.net sessions for situations like captcha validation (if your captcha library requires so). For such situations you can enable sessions for your specific web-api calls like below.
//WebApi Session
protected void Application_PostAuthorizeRequest()
{
if (HttpContext.Current == null)
return;
var request = HttpContext.Current.Request;
if(RequireSession(request))
HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
private static bool RequireSession(HttpRequest request)
{
return request.AppRelativeCurrentExecutionFilePath == "~/api/user" && request.HttpMethod == "POST";
}
Not: If you enable asp.net mvc sessions for all your web-api calls than your requests will be processed sequentially. Not recommended!
Concurrent Requests and Session State

Resources