ASP.NET Core MVC/WebAPI Authentication Schemes plus Anonymous - c#

I'm having an issue with a website plus API I'm writing. These are in the same project, if that matters.
Reduced to its simplest form, it's a catalogue website and API. You have products in a database and pages which display product information. You also have other pages which allow editing this information and adding new products, etc.
There are three ways you can do this:
Anonymous users can list products and view public information about them on the website.
Signed-in users can list, view (including private info), edit, create and delete products on the website.
Users with a valid API key can list, view (including private info), edit, create and delete products using the API.
The problem I'm having is that the website uses AJAX calls to the API, and these only work if the user of the website is authenticated. Calling the API without an authentication cookie or an API key fails by design.
What would be the recommended way of identifying the unauthenticated website to the back-end API in a secure way that allows it to work?
The ideas I've had include:
A special API key for the website, but it would by necessity be visible to the world at large somewhere in the Javascript code and therefore something someone could use to access the API themselves and bypass any rate limiting I wanted to implement.
I considered setting something in the session on the web controllers which could then be verified in the API controllers, but I encountered issues where unauthenticated calls to the API redirect to the login page on the Account controller, which then sets the relevant session variable, which means subsequent API calls succeed whether legitimately authenticated or not. This seems like the most promising option, but I'm not familiar enough with ASP.NET Core's workings to make it robust.

You should use Jason Web Token Authentication, to implement one in your API please check the following the link:
https://medium.com/#adegokesimi/implementing-jwt-and-refresh-token-in-net-core-2-2-web-api-b21ef6de2a19
By using JWT authentication in the pipe line of your WebApi your problem will be solved.
Also, you can use a ASP.NET Core identity system for things like roles that can be implemented on specific controller methods, for example, "EDIT" can be allowed only to role admin, etc.
Kind regards,
.js

Related

React SPA with .net core API, authentication

I would like to write a SPA application in React that will communicate with the .net core API.
I think it would be easier to have two separate projects (API + UI) on different domains.
API should be protected, that only authenticated users could make requests.
In react i'd like to have login and registration forms that will allow me to register and login users, and also I would like to have social providers. I would like to create whole UI for managing users in react SPA, and saving this data using API.
I did a lot of research, and I'm a little confused.
I would really like to use Core Identity because it simply looks like made for it
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0
it has a ready to go model of Users, Claims, Roles etc.
it has built in services for managing passwords, users, roles etc
it has features to customize authentication schemes, policies, roles etc,
there are lot of reasons why i think this is a good solution.
Unfortunatelly, on the documentation site there is an information that for SPA integration it works combined with Identity Server.
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-5.0
Last year I went throug every episode of this tutorial https://www.youtube.com/watch?v=Fhfvbl_KbWo&ab_channel=RawCodingRawCoding (btw. great tutorial), and I'm pretty sure, that I don't want to use Identity Server 4 for this scenario. As far as I know - this is the best solution when you want to have SSO for multiple applications, and you would like to provide one common way to authenticate user for all of it. And it has it's own UI for managing user registration, login and managing. This is not what I need - I just want to have it all written in React, cause I want all application to have the same mui theme without redirects to Identity Server.
But maybe I'm wrong, and Identity Server will work for me. But I found it to be quite lot of work to provide my own UI rather than MVC
(https://medium.com/#piotrkarpaa/using-spa-react-angular-ui-with-identity-server-4-dc1f57e90b2c)
For now I think, that I should use Identity Core on the backend, and communicate with it from React SPA with custom controllers like in here:
https://www.c-sharpcorner.com/article/authentication-and-authorization-in-asp-net-core-web-api-with-json-web-tokens/
Authenticating React SPA with API with JWT token - I think that this will work according to this example:
https://www.youtube.com/watch?v=FSUa8Vd-td0&ab_channel=Geek%27sLesson - but in here this is without Identity Core.
But I'm not sure that this is the best approach, and I don't know if I will be able to add Social Providers this way.
Also, I found serveral tutorials how to comine React App with .net core backend (and authentication) like this one:
https://www.red-gate.com/simple-talk/development/dotnet-development/integrate-create-react-app-with-net-core-5/
but I would like to have two separate applications, API and UI.
What is the best approach to achieve this goal?
EDIT:
Few months later, I already have SPA application, API and IS4. There is lot of problems to make Identity Server views (registration, login etc) look similar to SPA Application. (React app in MUI, MVC with bootstrap... ).
Now I think it was a bad decision, causing lot of problems:
2 way integration of users from API and Identity Server 4
changes in SPA layout, styles, colors - it all needs to be maintened on Identity Server 4 too
Bad user expirience - editing user profile on another application, on another domain with slightly different styles
Now I'm about to rewrite application, not to use Identity Server 4. Components for registration, login and editing user profile will be in SPA application, maintaining users will be done using API.
The only think I do not know is how can I use social providers with this aproach?
My question is still remaining without answer, can someone help me with providing proper solution?
Finally I found proper solution for me:
https://mahdikarimipour.com/blog/google-auth-for-react-with-aspnet-identity
thank you for your post: Mahdi Karimipour

Microsoft Identtiy & Identity Server 4 process flow relationships

I'm working on building a series of micro-services using Aspnet Core. A mobile application, desktop application and web-application will consume the services over Http REST APIs.
For user auth, I'm utilizing the Aspnet Core Identity platform, but I'm exposing the creation of user accounts via a REST API. The clients make a REST call with the credential information and my API uses the Microsoft Identity APIs to provision the user. The user would be authorized to hit the individual resource servers with an auth server using IdentityServer4.
I have two questions that I've not been able to find clear guidance on from a security stand-point. Should the Aspnet Core project that utilizes Microsoft Identity for user creation be in an independent Aspnet Core project from the project that handles auth via IdentityServer4? Are there downsides do separating the two out that I need to consider?
The Microsoft Identity API has template and Razor Views that can be used to handle the auth from a server-side perspective, including redirects on account creation or sign-in etc. If I'm doing everything via SPA or Client-side native apps, is there anything wrong with just providing a POST API that accepts the user information, creates the account via UserManager<T> and returns the UserId?
I want to provide a dedicated sign-in page, similar to FB/Google/Twitter etc for Auth to happen across any app that wants to authorize a user for my services. I don't typically see account creation as part of the OAuth process though. Is it typical that you would allow for redirects to an account creation page, that redirects back to a client upon successful account creation or is that process typically just used for Auth via OAuth flows?
I would suggest to consider using one service for IDS4 and ASP.NET Identity since they can be integrated and give you the full functionality you're looking for(auth, and users management).
IDS4 has examples and good documentations regarding that.
To me, I think separating them would be an over engineering.
one example: when IDS4 generate access token for a user, you should get claims, roles and validate username and password, all of that are stored in ASP.NET Identity.
So for more details you can check the docs of Identity Server 4: http://docs.identityserver.io/en/latest/quickstarts/0_overview.html
or it's my pleasure to check my little blog post that I tried to give some more detailed and step by step.
https://feras.blog/how-to-use-asp-net-identity-and-identityserver4-in-your-solution/
Start with IDS4 link because it might be enough :)
The main point when thinking about security management UI is how to secure that UI. And the most safe approach for today is cookie-based auth with same-site cookie (the way, MVC uses by default). Consider that when and if selecting serverless SPA pattern. For management purposes-app having strict backend is much more secure than token-based access to distributed api-s.
Regarding the application hosting, #VidmantasBlazevicius is absolutely right, there is no the only strategy: hosting all the services in one app is simpler, so it better fit lo to middle loaded systems. But with raise of the number of users and authentication requests, you might want to scale, and separating management UI from authentication is one of the ways to handle that.

ASP.Net MVC Get more information from external logins

I have an asp.net MVC web application and i try to add some fields from the external login providers, so that i would make it easier for my users to register for the first time.
How can i receive more information like birth-date, languages, etc?
(For now, everything works fine. My question is only about how to receive more information.)
You can perform external login using Google OAuth2 Sign-on.
https://learn.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on

How to implement IIS authentication in an asp.net web api project?

I've been tasked with enabling authentication and authorization for our project's api. The main goal is to protect the methods from misuse, however we also need to enable a developer from another company to call the methods in their code.
Being new to authentication and authorization I'm overwhelmed with the many different options available for .NET etc. Some techniques look promising until you read that they pass credentials in plain text (basic auth?) or have other issues etc... I'm just looking for a reliable and safe approach.
I'm using IIS to host the web api, and I have seen that one such option is to authenticate at the 'host level'. My supervisor has mentioned this is the preferred approach.
I have looked at many threads and videos regarding authenticating in IIS. From what I can work out, such a solution alerts the user that a certain action requires authentication and to enter their credentials.
My issues are as follows:
Given the other developer is not a member of our domain, how can they authenticate using their (windows?) credentials. Is there an alternative to windows authentication?
How will requiring authorization on certain api actions impact the function of the site normally? I.e. will I have to pass valid credentials to the api in my code, for each request?
Overall I'm just a bit uncertain on how this all works and I appreciate any advice given.

Cookie authentication for MVC and OAuth for WebAPI in the same app

I have an asp.net application that has both MVC controllers and WebAPI controllers.
For cookie authentication I use app.UseCookieAuthentication(... middleware with DefaultAuthenticationTypes.ApplicationCookie authentication type.
For OAuth I use app.UseOAuthBearerTokens(... middleware.
For MVC routes I have used AuthorizeAttribute as global to prevent anonymous access. Interesting thing is I can get data from MVC controllers too having access token recieved through oauth.
I understand that oauth middleware sets current user while processing request with token. Now I added additional attribute for MVC part to reject users with authentication type != DefaultAuthenticationTypes.ApplicationCookie.
Now requests with tokens will work only for WebAPI. Is this a good approach or am I doing something wrong?
Is this a good approach?
Not really, its not the authentication mechanism you want to prevent, you are likely to want to restrict access to just your MVC front end, the razor templates. You could use a custom filter similar to how it is explained in this response to ASP.NET MVC preventing users from direct URL except your filter should check that Request.Url.Host is in your list of known endpoints.
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace Customer.Filters
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PreventFromUrl : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// MVC requests will originate from the same host as the server
// external apps may not have a referrer or it will be from a different domain
// If you have your own non-mvc code, in the same domain, we trust you know what you're doing :)
if (filterContext.HttpContext.Request.UrlReferrer == null
|| filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
{
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
}
}
}
If a Filter does not work, consider moving your Web API to a separate project, but be aware that this is really just a security by obscurity measure, it is still possible to use cookie based authentication to obtain access to your MVC endpoints once the caller has authenticated.
Using the authentication type alone does not provide any additional security benefits, you are just saying that each route requires specific way to authenticate, you are not doing anything to deny access itself.
You are expecting all non-MVC traffic to use OAuth, but because your site supports cookies, external apps could still programmatically and legitimately use cookie based authentication and gain access to your MVC controller endpoints.
is it important to deny access to your MVC controllers?
Your application logic should always be written with security in mind, your server-side controllers should not rely on the front end to validate and sanitise user inputs, any business rules and validation expressed in the user interface should also be evaluated in the controller logic.
Perform and design validation and business rules in the back-end first, in your controllers.
Because front end scripts are executed on the client they are therefor in a much more vulnerable state. It is trivial to capture and monitor the traffic that the front end sends back to the client, there for it you can work around client-side validations by manipulating the data before sending it back to the server.
Or worse, evolving client technologies might create scenarios where your client-side scripts and logic do not evaluate the way you originally expected, accidentally allowing un-sanitised or invalid data to flow through.
When the controller performs all business rule validation, as we are conditioned to do in Web API, then in general it should not really matter if the end client is your expected MVC client or something custom written. Even if someone wrote an app to automate or impersonate a valid user, If the caller has legitimately authenticated, let them in, because they could otherwise login directly through the MVC site manually or through the API.
It is pretty easy in MVC apps to put validation in the user interface level and to skip performing the same checks in the server-side, in this scenario, or when your MVC app exposes more data than you want to allow external clients to access it can become important to deny access to these MVC routes for non-mvc callers.
In general, supporting multiple authentication mechanisms is a good approach for an API because it broadens the options that clients can use to interact with the API. So supporting multiple types of auth to access the WebAPI routes IS a good approach.
This scenario makes it easy for your front end to access data through both the MVC controllers and the WebAPI. A common scenario that I encounter is when we use the API to secure access to external files and images. we can put the URL for the resource endpoint directly into and use the auth cookie that is already in the user's browser to access through the API.
Supporting Mutliple Authentication Mechanisms or Providers will increase the attack surface of your API. This not necessarily a bad thing, but it is something to be aware of and to audit.
Increased attack surface does not automatically mean that the service is more vulnerable, but it does mean that there are more points of potential failure in your authentication.

Categories