I have an ASP.NET Core 2.2 website. It's a portal. Some pages are served by ASP MVC Views, other pages redirect to Angular SPAs.
Some views of the ASP.NET site and some Angular apps need to be behind username/password.
For Angular SPAs it makes sense to use JWT authentication. There is a login component that makes and API call, gets back a JWT token and stores it in the local storage. This works because the JwtBearer scheme was used in ASP.NET for authentication. But once I authenticated with JWT, how do I make plain (not-SPA) ASP.NET Views/Routes respect that JWT token?
Is there a way to force browsers to automatically append the Authorization header based on a Jwt token?
Is that possible to use cookie-based authentication in .NET along side of Jwt authentication?
Is there another way?
Thanks.
Related
I am developing an angular +.net core web app(not to be confused with .net core MVC web app).
My UI client uses angular, my backend web api's use .net core 6. I am using external IDP to authenticate my angular app for that I am using AddOpenIdConnect. All though I am not using MVC for my other APIs(using web api type controller) but I pulled in couple of MVC controller(Home and Account) from the sample app present in external IDP's sample project(as I could not find a way how to achieve it with my APIs).
On login button press in my angular app I call this method of Account controller which redirects me to external IDP. After successful authentication I am being redirected to my angular app's landing page (http://localhost:4200/admin) which solves my purpose as far as SSO is concerned. Also in OnTokenValidated event I am getting the access token as well.
Now the problem I have with this approach is:
How can I return this token to my angular app(which is an independent SPA) so that it can be used as authguard for the angular app and for safe guarding other api end points?
I am thinking of making another end point which angular app would call after successful redirection which would return the claims and access token to UI. I tried fetching it from HTTPContext in the end point that I made but it is coming out to be null and User.IsAuthenticated as false.
How can I secure my web api end points with this same access token? I am thinking of using the access token returned to UI after redirection for authentication and then it can be sent back to backend apis in header for authentication. How can I achieve that?
All the example and sample code(even on IDP's website) use .net core MVC. Did I make a mistake by making it a web api project?
I have two main projects in my solution, one is a .NET 5 Core MVC web application that is used as our front-end application with Identity for authentication and authorization, and it is currently directly connected to a Database layer(different project) that is responsible for CRUD operations using Entity Framework.
The other project is a .NET 5 Web API application. And we would like to move our controllers' logic from the MVC app to the Web API app, so that only the API project will have access to the database layer.
I'm not really experienced with authorization techniques apart from some basic stuff, so I'm stuck with an issue right now. How can I move the Identity authorization to the Web API project? I understand that on the MVC app, a Cookie is used to handle the authorizations but as I've seen the recommended approach for most Web API apps, is to use a JWT to authorize requests. However, in my scenario, since I would like to authorize the user(from the browser) on each request, would a Cookie authorization be possible ? Or should I store a JWT token on the browser and pass it along on each request?
Thank you
Why do you need to move the MVC controller to the Web API Project? If the controllers are separate than that is even better!
Here in short how JWT based authentication works:
The JWT token has tow components - an Auth token and a Refresh token.
The Auth token is used to authorize the requests and the Refresh token is used to renew the Auth token when it expires.
The Auth token also contains some user claims like Name, Id, Email etc.
You make the user re-login when both the Auth and Refresh token expires.
For Web API JWT authentication is best.
Use your MVC controllers to render and handle the page flows and the Web API controllers to return data from the Database. For your current structure you can do the followings:
Have the MVC Auth controller consume an API from the Web API project and then maintain the Identity cookie as is now. The API will return a token if username and password works.
The Web API project will parse and validate the token. All you have to do is to check if Web API is returning a 401 or not. 401 would be when the token is invalid or expired
In your MVC project, switch from Asp.net Identity cookie to store the JWT token on the client side (From MVC project). And pass it along all requests to the Web API controllers.
I've REST services (Web API) and admin panel (MVC) in one project on ASP.NET Core 2.1. I want to secure my API with JWT token, and my MVC pages with cookies. Can I combinate these two authentication ways. How to configure my Startup.cs, Authorize attribute and sign in functionality.
I suppose you should use an OAuth 2.0 framework. please check IdentityServer4 it enables many features in your applications.
IdentityServer is middleware that adds the spec compliant OpenID
Connect and OAuth 2.0 endpoints to an arbitrary ASP.NET Core
application.
Typically, you build (or re-use) an application that contains a login
and logout page (and maybe consent - depending on your needs), and the
IdentityServer middleware adds the necessary protocol heads to it, so
that client applications can talk to it using those standard
protocols.
I've seen a lot of articles that cover using JWT Tokens in API scenarios. How do I include the JWT Token in my request for a web page?
My ASP.NET Core app has both web pages and API methods so I want to use cookies for the web and token for API.
The way we do it here with Asp.Net, is our auth layer looks for either a cookie or an Authorization header. It pulls the token from either location. This article might be helpful:
http://auth0.com/blog/cookies-vs-tokens-definitive-guide
This takes some custom code, but its not too difficult really. Make your own AuthenticationHandler.
https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2
That excellent article will guide you through every step of the process.
There is an existing mvc 3 application that is using asp.net Membership authentication (subclass of System.Web.Security.MembershipProvider). This application was only accessed using web browser.
Now, there is a need for the application to support a Mobile App, and I have already introduced WebApi 2 Controllers into the project for handling the Mobile App requests.
The problem is that I don't have a clear thought of how to Authenticate the Mobile App users.
It seems that I have to provide Token type authenticating mechanism where the Mobile App has to submit the Token (issued after authenticating) with each request. But I am not sure how to implement it (like what frameworks/packages to use), and get it working side by side with the existing MembershipProvider
So, how do I provide a way to authenticate Web Api requests, and also retain existing asp.net MembershipProvider for MVC Controller requests.
Also, if this could be done better in some other way ?
It doesn't have to be "token" that authenticate mobile users.
The notion of tokens used to authenticate webapi requests got a lot of attention because of the OAuth2 protocol that has been adopted to the .NET world by the DotnetOpenAuth and then the OWIN. OAuth2 supports multiple "flows" and what is interesting is that beside "passive" flows (where browser redirects to an external login page) there are also "active" flows (designed for active clients like mobile apps).
Thus, switching to OAuth2 means that you are using a coherent authentication protocol supporting all major scenarios.
One of the possible approaches for you (and you seem to be interested) is to adopt the token approach to authenticate webapi requests. This is possible but this means that you have two different authentication approaches side-by-side, the cookie-based forms authentication for passive clients and token-based authentication for active clients.
I would say this kind of smells.
I would rather think of a uniform approach.
Either move towards OAuth2 completely, which means you adopt DotnetOpenAuth/OWIN for both passive and active clients.
Or you stick with Forms Authentication and just enable it for your active clients.
The latter is rather simple. Instead of carrying tokens, your active clients carry forms authentication cookie. To issue such cookies, you just expose an anonymous webapi method that expects a login and password and appends a forms cookie to the response.
Assuming you clients support cookies, forms cookie issued by the server are used in consecutive requests and all you have to do is to have the Authorize attribute over your web api methods. The forms module will pick up the cookie and populate the IPrincipal for the lifetime of requests just like it does for regular requests.
To summarize:
Moving towards token-based authentication:
Pros:
in future you could easily handle more complicated authentication scenarios (like for example using external authentication providers)
token-based OAuth2 is commonly used nowadays so you can more easily integrate with other applications
Cons:
migration could cost: you first have to gain the knowledge, do some R&D and then migrate
Sticking with forms authentication:
Pros:
you already have it and you just enable it for active clients
Cons:
forms authentication is not really "an authentication protocol". This means there is no obvious way to easily integrate with external authentication providers/consumers