C# .NET 5.0 MVC JWT Middleware authorization header - c#

The problem is that when I login in through the MVC controller post method, i get the JWT token and save it in the HttpContext authorization header, the code jumps to middleware where i can see the token in the context, but as soon as the invoke functions call _next(context) delegate, there is no more authorization header. How do i solve this? Is there some good practice how to pass the token from mvc controller to the middleware so i could attach account to the context?
Thank you very much

One idea is that you need to set the SaveToken to true here:
.AddOpenIdConnect(options =>
{
...
options.SaveTokens = true;
If not, can you post our startup class to the question?

Storing the token in HttpContext.Session solved the problem. Thanks though.

Related

Asp.Net Core 2.2 - Understanding Authentication Middleware and External Logins

I have been trying to wrap my head around this concept but have many questions and unfortunately, all official documents and tutorials are based on Visual Studio templates with individual user accounts.
My goal is pretty straightforward I believe. I have a web application which will only support external provider logins (namely: Facebook, Twitter, and LinkedIn). I do not want to support cookie authentication since there won't be a support for custom username/password.
My first problem is to define a default AuthenticationScheme. Below is my startup.cs:
services.AddAuthentication()
.AddFacebook(/* options */)
.AddTwitter(/* options */)
If I define a controller action with Authorize attribute I get no default authentication scheme defined error when I hit that route. However, I want users to be redirected to my login route if they are unauthorized. If I modify startup.cs like below it all works but then I think I support cookie (old forms authentication?) authentication which I don't want to.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddFacebook(/* options */)
My other issue is that I don't know what happens under the hood of AddFacebook() call. If I set up my middleware this way and log in with Facebook I magically get all the necessary tokens, claims and suddenly I have an application cookie set and my fb_login callback route can access to Facebook's token! When I check the network requests I see there is a hit to the signin-facebook route -which I didn't define- and I guess under the hood it calls HttpContext.SignInAsync() etc... but if I refresh my fb-login callback and check if
HttpContext.AuthenticateAsync(FacebookDefaults.AuthenticationScheme)
returns Success = true no! it returns false! But it was true just one second ago?
Also, when should I be using methods like AuthenticateAsync() and SignInAsync()?
Long story short I need a tutorial or documentation that explains this middleware without asp.net Identity framework, EntityFramework and templates.
I want to understand how a simple AddFacebook() call binds everything, and if I want to manually do that (say with AddOauth) how can I achieve the same functionality?
I'm not a fan of "automagically working" code so if someone can explain what's going on here I'd be very appreciated.
Cookie auth is used to persist the authenticated state between the requests. There is no substitute for this, and no it's not the same as forms auth, though cookies are used in both cases. The reason for that is simply that cookies are what makes state work over the HTTP protocol, which is itself stateless. If exclude the use of cookies, then there is no other mechanism to maintain state.
Using something like the Facebook auth scheme directly authorizes the initial request, but again, because there is no state, the next request is no longer authenticated without going through the Facebook OAuth flow again.
Long and short, the other auth schemes are there for things like APIs, where each request is typically authenticated individually via something like the Authorization header. A web browser doesn't work this way, and instead relies on cookies handle subsequent authorization. No cookies, no auth.

ASP.NET Core: JWT token with Scopes

Background
I have a ASP.NET core (v2.1) project that contains an API. This API is access restricted by JWT bearer.
My server expose an endpoint for login:
POST http://example.com/api/login
After attaching the token to the request, I can call one of the server methods (GET or DELETE:
GET http://example.com/api/1234
or
DELETE http://example.com/api/1234
Target
I want to implement "another type" of token that will allow access only to specific scope. Let's say that we want to give access just for GET method. So, if you have this token - you can GET the resource but not to DELETE it.
Wondering if this is possible with JWT bearer token? If yes, how?
Thanks!
You shouldn't do this with the token itself. The token is used to authenticate that a user is who they claim to be. You should instead look at using the roles to authorise an action and assign different users roles to restrict access to delete verbs.
This article should be able to explain further
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.1
JWT Bearer token should be used for authentication mechanism but what you are talking about is Authorization and thus your approach is wrong seems. You should rather use the Authorization pipeline and implement proper Roles/Policy based authorization which will restrict access to those Api endpoints.

Authorization has been denied for this request. Postman

New to Owin authorization and currently exploring.
I can now successfully get the token from the token host
I now try to access a controller with the [Authorize] attribute but seem to be getting a Authorization has been denied for this request issue.
I used the returned token as a bearer token but doesnt seem to work in post man. Any help would be appreciated.
Thanks
Shoot it was just a matter of order in the Startup.cs
I created called ConfigureAuth after WebApiConfig.Register(config); #.#

How do you stop the Identity middleware from redirecting on a 401?

Working with AspNetCore RC2 (and now v1)... using a mix of JWT bearer tokens and the Identity middleware for authentication and authorization. Went though the tutorial (linked) and got token authentication and authorization working with the WebAPI.
I need "app.UseIdentity()" in the Startup.cs Configuration in order to use the Identity framework to manage users and roles. The problems is: it's causing the WebAPI to redirect to "account/login" instead of simply returning a 401 (unauthorized) status when an anonymous user tries to hit an endpoint with [Authorize] on it.
I've seen people talk about how to stop this when using cookie authentication, but that doesn't help, as I'm only using tokens.
Can anyone point me in a direction on how to tell the Identity middleware to stop redirecting unauthorized attempts? (If code is needed, let me know.) :)
This appears to have stopped the redirect (Startup.cs, ConfigureServices method):
services.Configure<IdentityOptions>(options =>
{
options.Cookies.ApplicationCookie.AutomaticAuthenticate = false;
options.Cookies.ApplicationCookie.AutomaticChallenge = false;
options.Cookies.ApplicationCookie.LoginPath = PathString.Empty;
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedEmail = true;
});

Owin Authentication Single Sign-Out

I've got a custom Authentication middleware working for single sign-on. I'm wondering how I should go about implementing a single sign-out solution.
I need to call Authentication.Signout() to signout of my application, but I then need to redirect the user to the sign out endpoint of our custom STS. Where should I handle this? Invoke? ApplyResponseGrant? Not in the handler at all, but just a manual redirect?
edit:
This is an MVC app. I have everything working EXCEPT linking the local logout to logging out of the STS. Adding my existing code here would do nothing but obfuscate my question, IMO. If there is a specific piece of code that would help, let me know and I'll add it.
Ideally, I'd like some sort of event or flag that tells me the user is signing out, and then change the response into a 302 to the external logout. If I put this code in the ApplyResponseGrant, I have a feeling it will prevent the CookieAuthentication middleware from clearing the auth cookie. If I put this code in the Logout controller action (after a call to Authentication.SignOut()), then I leave it up to each application to handle the single sign off.
I got it working. Here's what I did.
In my AccountController, I added a Logout action that returns a Redirect("/signout-custom").
In my OWIN handler, I watch for that URL in the Invoke method, call my remote sign out endpoint, the local sign out method, and stop OWIN processing.
public override async Task<bool> InvokeAsync() {
//other code
if (Request.Path == Options.LogoutCallbackPath) {
Context.Authentication.SignOut(Options.AuthenticationType);
Response.Redirect(WebUtilities.AddQueryString(Options.ClauthLogoutUri, "returnUrl", "http://localhost:62506/Home/About"));
return true;
}
//other code
}
The redirect does not interrupt the OWIN flow, so the CookieAuthentication middleware still runs and clears the local auth cookie as it should.

Categories

Resources