ASP.NET MVC + Angular app with only token auth and no cookie - angularjs

I have an application built by a previous developer that uses OWIN middleware with both cookie and OAuth tokens. It is an ASP.NET MVC app that is only using MVC views/controllers for login and a home view that hosts an entirely separate Angular app.
Bearer tokens are used to authenticate to the API once the app is entirely loaded but an auth cookie is used to load the initial scaffold MVC home view enclosing the ng app.
My issue is having a business requirement to allow users to login with unique credentials per browser tab therefore cookies cannot be used but simply use a session-based token to keep them separate.
Can an ASP.NET MVC app fundamentally operate without cookie-based auth?
If I can remove cookie auth and rely on tokens only this will solve my issue of having to rewrite the angular outer frame in solely angular code and reimplement login pathway.
A note: I am implementing IdentityServer3 and I found all samples there and elsewhere always have cookie auth as part of the mix thus my question here.

I think what you want to do here is the following:
Add an [AllowAnonymous] on the Home controller
In the application that is loaded by the Home page, use a browser side package like oidc-client to perform a user login. This will return an id and an access token.
Inject the access token in you REST service requests.
Use UseIdentityServerBearerTokenAuthentication to filter and authenticate bearer tokens in the WEB API server.

Related

Authentication and Authorization in React app

In a .NET app I can add authentication and authorization using web.config and/or IIS. I can also use [Authorize (Roles = "RoleABC")] in a MVC app's controller or action. And even extend the AuthorizationAttribute
I'm looking into creating a React app for intranet use, and reading these tutorials (ReactJS and MS), but can't find authentication/authorization details.
Even though the app will be Single Page App, I still would like to authenticate and authorize users for certain options within the app, just like I can do in MVC app.
Is the only option to do that way is creating Blazor app instead?
For authentication and authorization, you should use auth tokens (like JWT). Your backend should create an auth token when a client logs in to the system and sends it to the client. Your server also should send the authenticated user information to the client (react app) so that you can render correct pages according to the user type. For example, you can render the admin page for an admin type of user, and the guest page for a guest type of user. You can save this user data as JSON in Redux. Hence you can access the user data from any component of your react. Also, in your backend, you must restrict the endpoints according to the auth token which is sent by the client. In the backend of my app, I follow the below steps:
Authentication check -> Authorization check -> controller (endpoint) -> result
React isn't opinionated on this, so it's up to you to design the implementation. A basic way to do this is:
Log in and obtain an authorized JWT token from the backend and include the account ID when you sign it
Store the JWT token in localStorage, store the account info in Redux
Conditionally limit routes based on account info (ie. admin group) on the front end
Have every auth-required API call include the JWT token in the x-auth-token header, then on the backend use middleware to check if it's still valid. You can then also decode the account ID in order to check its privileges so that you can limit API access
This may be helpful: https://medium.com/#faizanv/authentication-for-your-react-and-express-application-w-json-web-tokens-923515826e0#5f52
Not sure whether you still need this - I personally feel we should have something bridging the authZ gap between server and client to make it easy. So I spent a few days on a github project for this purpose, here it is: authzyin.
What I tried to do is to leverage policy based authorization from asp.net core - which I think it's very cool - and automatically bring the same definition to the client to use in React via hooks.
For authentication I am using msal.js against AAD - so authN is done on the client and jwt bearer token auth is used for all requests.
It has a client lib and a server lib which can be used together or separately. Of course it might still be lacking some features - please feel free to take it as a reference (contribution is also welcome).

how to protect react.js spa with .net core api

I am trying to protect a react.js spa app with adal login and authenticate with .net core wepApi.
I am able to get JWT from azure invoked by react SPA (using react-adal module) and retrieve basic user information.
Now the joy begins
As most MSFT examples are based on their mvc approach, they have a password to sign token in the webconfig file, which is not accessible for frontend application.
How then I could sign the JWT token using a password without pushing it to the SPA app as that could be read in a web console?
One of my ideas is to initiate login in the SPA, then use a webapi endpoint as a redirect link (and provide a connection id in state field) and then by ajax I could do redirect on the SPA, but still there is no signature on the JWT.
my partial solution at the moment is:
have react-adal used to validate if user is logged-in
when there is no token, then react-adal authenticates, but redirection is on a special page when I am grabbing the token and store it in database. The trick here is: there is a need to change hash to query-string to grab the token serverside (as all after # is not forwarded to web-server), so a simple javascrip that replaces # with ? and redirects to another endpoint.
then redirect to the main application
As the URL is only used for redirects (after adal login ) - that is a typical man-in-the-middle scenario, but gives an ability to generate own token.

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

Moving Asp.Net WebAPI into a Separate Site from Asp.Net MVC site for AngularJS App

We have a Asp.Net MVC 5.0 project which uses AngularJS for front end. The project has WebAPI Controller in the same project and it is deployed to same website. The application is built with Individual User Account project template and uses Asp.Net Identity and Claims. There is file upload module where users upload some 100MB+ files that goes through webapi and ng-file-upload plugin. Due to increase in user base we wanted to quickly improve the upload speed by separating API alone into a separate site in a new server and scale it when needed. Since API controller is currently under ASP.Net MVC solution which uses OWIN cookie authentication the API is authorized by the cookie authentication middleware.
What is the quick way to get the API into a separate site? I beleive we need to implement OAUTH token based on the MVC site and make the new API site to consume the token by enabling CORS. If we do this we are not sure if we need to remove cookie based authentication and re-implement authentication using the new token based authentication. Are there any other approach we can take here by still using cookie based authentication for the Asp.Net MVC site and separating api into a new site?
Note- We also plan to build Mobile app using this API so we believe we have to separate the webapi into a separate site and bring OAuth token based authorization.
Thanks in advance!
Regards,
Bala
If your mvc site is going to be only client side code only without any major back-end c#. This requires no security as your data comes from API which is what needs to be secured. If you dont want to seperate the two in different domains. Angular will need to read the user information being sent from the server which is why HTTPs only encrypted cookie will not work. If they are going to be different server and domain, plus you need multiple consumers of the API, you should move to oAuth and bearer token based login with refreh tokens and the whole thing. This way you can scale the api into multiple load balancers and still use the bearer token and this would be stateless. That being said you can still achieve this with cookie by storing the token in cookie that way, angular can parse and use the values and the api can validate the signature of the token and use the values. With them having to be on the same domain so they can share the cookie. This can be done without using cookie and simply using LocalStorage as well.

IdentityServer 3 refresh tokens silently

I'm using Identity Server 3 to authenticate / authorize a user in an MVC application.
The MVC application uses the UseOpenIdConnectAuthentication method from IAppBuilder.
My MVC application has only one MVC controller which creates and Angular application.
Right now, when I make an ajax call and I get the response that the token has expired, I show a pop-up with a reload button that redirects that user to an action from HomeController which re authorizes the user through IS3 with a redirect.
My question - is there a way of doing this silently without having to use the pop-up and do the redirect?
Perhaps have an iFrame in the page that periodically makes requests to that action and saves the new tokens?
Or something similar ?
Is this doable in an Angular application which also uses a server side for authentication ?
Thanks you
If you want to renew the access token at the server side (Authorization code flow / Hybrid flow), you could make use of OIDC refresh tokens.
I believe you are looking for client side libraries (SPA client - Implicit flow) to refresh the Access tokens. Yes. This is possible via iframe. Have a look at the oidc-client JS library (look for signinSilent / automaticSilentRenew ) which renews Access tokens via iframe

Resources