Query param login with cookie authentication in ASP.NET Core - asp.net-core

I have a legacy ASP.NET site that needs to be ported to ASP.NET Core due to server migration. The app is an ASP.NET MVC site using cookie login and auth. There is also a legacy query param login, where all pages accept ?u=<user>&p=<pwd>.
I tried adding an AuthenticationHandler, but Cookie authN only forward to login page instead of allowing the second Scheme handler to try authN. There is no OnAuthorization to override in Controller anymore (all app controllers have the same base class).
I also need Cookie login to be valid after first request (only this request have the query params). Following requests should use cookie for login.
What is the correct (recommended) way to implement this "query login" in ASP.NET core?
How can I hook into Cookie AuthN failure (no cookie), check query params, provide principal/identity and do cookie login (HttpContext.SignInAsync).
Is there any documentation for ASP.NET core about how AuthN and AuthZ interact and the different steps the middleware go through for Auth?

Related

How to implement an authentication within Blazor Server App with JWT from Web API

I have a Blazor Server app which wants to connect to a .Net Core WebApi. The app should send an authentication request and the WebApi returns a JWT containing user data. For any further communication with the WebApi the JWT should be used to authorize against it.
I'd like to ensure that only authenticated users can access the server app. If someone is not authenticated he or she should be redirected to a login page.
Up to now I've used a combination of default Identity with AzureAD authentication.
Is there any option to have a JWT authentication working the same way?

ASP.net Core Authentication with Cookie Authentication and OpenIdConnect : how to redirect after being logged

I'm working on an API core application with .NET core 5. I protected the API with the following methods:
Cookie authentication
OpenIdConnect authentication (tokens kept in cookies, provided by an identity provider)
The authentication works well:
If i'm not logged, i call an api endpoint (on a browser), and i'm redirected to Identity provider login page.
I log in the browser, then i'm redirected to my endpoint result.
Instead of that behaviour, after being logged in, i'd like to be redirected to a specific URI, but i don't find what to configure for that (maybe doing something on some events, like CookieAuthenticationEvents or OpenIdConnectEvents ?)
Thank you

authorization middle-ware differences between mvc and api

Trying to get my around the the exact differences in setting up the authorization middle-ware for a MVC backend versus an API backend.
My understanding (basic) is that a controller decorated with the [Authorize] attribute will invoke an authorization handler to verify the identity of the client, and then
1) In the MVC backend, and if fails not authenticated, would redirect to a default login page where the use would input their credentials etc.
2) IN the case of an API back, the controller would simply respond with 401 message (redirect would not make sense in an API and the client, a SPA for example would have to figure out what to do next)
I would like to ask what differences exist when setting up the app builder in the startup class since I suppose the functionality of the authorization middleware is different depending on each case (one case redirects, while the other does not).
P.S. I am aware that MVC case will generally be using a cookie, while the API case would be JWT but was wondering where the decision to redirect or not is handled / configured?
If adding authorization middleware to application using app.UseAuthorization() , and apply Authorize attribute on controller/action means the controller/action requires a signed in user , if user is not authenticated , the authentication schema will be challenged . There is no different logic in MVC and web api .
MVC will redirect is because you add the cookie authentication :
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
CookieAuthenticationDefaults.AuthenticationScheme passed to AddAuthentication sets the default authentication scheme for the app , so if user is not authenticated , cookie authentication is fired , and Account/Login is the default login path of Cookie authentication , so user will be redirect to that url .
On web api side , you will redirect to same path if you add cookie authentication also , but usually Web API is a service and doesn't have any UI elements. So, features such as redirection URL don't apply to a Web API. Moreover, a Web API can be consumed by variety of clients including Single Page Applications (SPAs) and non-browser clients. So we usually use JWT bearer authentication . JWT bearer authentication will return 401 if user is not authenticated and it won't(and not make sense) to redirect in web api .

What exactly does Challenge mean in Asp .Net Core 3?

I know that you can have authentication and authorization in asp .net core. So for example you can deny access to some resources using the Authorize attribute.
So for example if an user tries to access a resource that is not accessible then he might get redirected to the login page.
But I saw that there is a concept called Challenge in asp .net core. I don't know where it fits in all of this. From what I understood, if the user is not logged in it can redirect him to a page where he can log in.
This is covered in the official docs:
An authentication challenge is invoked by Authorization when an unauthenticated user requests an endpoint that requires authentication. An authentication challenge is issued, for example, when an anonymous user requests a restricted resource or follows a login link. Authorization invokes a challenge using the specified authentication scheme(s), or the default if none is specified. See ChallengeAsync. Authentication challenge examples include:
A cookie authentication scheme redirecting the user to a login page.
A JWT bearer scheme returning a 401 result with a www-authenticate: bearer header.
A challenge action should let the user know what authentication mechanism to use to access the requested resource.

oidc-client-js and basic authentication

Scenario
ASP.NET Core MVC (API) with IdentityServerAuthentication, Angular 2 with oidc-client-js. IdentityServer4, with ASP.NET Core Identity, as OP. Using Kestrel
nginx reverse proxy - SSL termination, Basic Authentication
oidc Implicit Flow
Authentication flow is as follows:
Browser navigates to app
Basic authentication in browser
Angular route guard notices (via oidc-client) that user is not signed in (or 401 is caught)
App navigates to unauthorized route
User clicks on sign in button, triggering UserManager (oidc-client) signinRedirect
Browser is redirected to OP (IdentityServer4)
User logs in at OP
Redirect to app signin-callback - i.e. UserManager signinRedirectCallback
Basic Authentication popup - because oidc-client calls connect/userinfo with Bearer authorization header.
Issue
The user is now stuck on step 9. The call is never made with the basic authentication header (or rather: both headers combined). The user can only cancel, which then yields a 401 on the request to the userinfo endpoint, leaving them signed out in the app.
Repeated tries would skip step 5 because the session cookie for the sign-in at the OP still exists.
I'm not entirely sure how the browser handles basic authentication, especially on requests made from js/angular. Could this be a bug in oidc-client-js?
I would guess that our app's authenticated HTTP requests would have to check if there already is an Authorization and add the bearer token to it (comma separated authorization headers, but only one such header). We already append an Authorization header with the bearer token if no Authorization header is yet send - but I cannot really experiment with that since this scenario does not even proceed far enough to make such api calls.
Everything works when Basic Authentication is not set
I'm using a local nginx during development to test HTTPS redirect, detection of SSL termination - and also the behaviour when Basic Authentication is added.
Everything works fine without Basic Authentication. X-Forwarded-For and X-Forwarded-Proto headers are interpreted correctly, HTTP is redirected to HTTPS etc.
Why do you even need Basic Authentication?
We do not want to have the application publicly available. OIDC based authentication has been added recently, as well as enforcing HTTPS etc. (app is not yet in production)