ValidateAntiForgeryToken error on first run of application - asp.net-mvc

When i publish my application from my local development server to the shared hosting server i get an error the first time someone logs in.
Error in Controller Account, Action method Login. Exception: The anti-forgery cookie token and form field token do not match.
I've tried adding a machinekey but that didn't seem to make a difference. I am refreshing the login page prior to trying to login. Seems like the same issue as this
The anti-forgery cookie token and form field token do not match in MVC 4
but the machine key didn't solve it. My application is ASP.Net 4.5.1 MVC5.1

Related

Authorize Attribute to handle valid user in Docker

I am running my .net core 5 application, namely Authentication Server and API Gateway, in Docker in Linux container. And controller class in the API GateWay contains an [Authorize] attributes to validate the user. Despite the user is valid (eg register and log in successfully), API Gate is unable allow the user to access the API. And here a part of my log that is complaining:
Failed to validate the token.Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match key:
kid: '6B7ACC520305BFDB4F7252DAEB2177CC091FAAE1'.
Exceptions caught:''.
Am I right to say that, is it due to the cookies generated by Identity Service 4; idsrv.session and .netcore related cookies failed to be shared.
This is because based on my observation when my micro-services are running in IIS. The Authentication Server, shall generates two mentioned cookies when user logs in successfully. And the mentioned cookies are "shared" among the rest of the micro-services, partly because they are in the same localhost but different port number.
When my application are migrated to Docker; the Authentication Server is able to generate the related cookies, the rest of the contains failed to get the cookies.
And as the result, which I'm guessing, that is the result that API Gateway is unable to authorise a valid user.
Hence, I am wondering is my understanding of Authorization is correct and how should I fix the issue with a valid user.
https://stackoverflow.com/a/58877655/3312570
The error code IDX10501 points to incorrect bearer token middleware.
Try adding cookies. Use the below code. My guess, it won't help.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();

IDX21323: RequireNonce is '[PII is hidden]'. OpenIdConnectProtocolValidationContext.Nonce was null, ValidatedIdToken.Payload.Nonce was not null

I have an ASSP.NET MVC web application MyWebApp which doesn't allow anonymous access to any page. There is an IdentityServer4 configured and once the user tries to open MyWebApp, he gets redirected to IdentityServer login page. (Hybrid Flow)
The user does not login and stays on that IdentityServer login page for long enough so the Nonce cookie on MyWebApp expires (15min default lifetime).
If he then proceeds with the login in IdentityServer (successful) and gets redirected back to MyWebApp, he gets the following error:
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolInvalidNonceException
IDX21323: RequireNonce is '[PII is hidden]'.
OpenIdConnectProtocolValidationContext.Nonce was null,
OpenIdConnectProtocol.ValidatedIdToken.Payload.Nonce was not null. The
nonce cannot be validated. If you don't need to check the nonce, set
OpenIdConnectProtocolValidator.RequireNonce to 'false'. Note if a
'nonce' is found it will be evaluated.
But since the user was successfully authenticated in IdentityServer, when he tries to access MyWebApp again, he gets redirected to IdentityServer and back to MyWebApp without having to enter username/password again. Yet the initial error is annoying. Anyone ever had such issue when the 'login' flow has started and the user goes 'AFK' for long enough that the 'Nonce' cookie expires and he can't finish the final validation? What would be a good way to handle that scenario?
Thanks in advance!
The error IDX21323: RequireNonce is '[PII is hidden]' is telling you that the URL that you were on at the time you made a request from MyWebApp to IdentityServer is different from the URL that IdentityServer redirected you to after authentication.
I encountered this error by having MyWebApp listening on multiple URLs. For example, the user would connect to www.MyWebApp.com. He would click Login and would be rediected to IdentityProvider. He would log in to IdentityProvider which would then issue him a cookie proving his identity for www.MyWebApp.com. However, IdentityProvider would then redirect him to my authentication endpoint (which I specified in my app) at MyWebApp.com. The change in the URL meant that his cookie was inaccessible to MyWebApp.com` and the app would throw the error.
When I then refreshed the page, I was already on MyWebApp.com. Now, when he clicked Login, he would be redirected to IdentityProvider. Because he was already logged in there, a cookie would be generated and given to MyWebApp.com (which is different from the last time when the user connected on www.MyWebApp.com). When IdentityProvider POSTed to my auth endpoint, the cookie was accessible to the application and the user was successfully logged in.
TL;DR. The URL that user connects on must match exactly the URL that your IdentityProvider redirects to after a successful authentication. Depending on how your app is configured, different cookie rules will apply. In my case, a difference in encryption (http vs https) or in subdomain (www vs no-www) caused users to seemingly have the IDX21323 error PII is hidden at random
Inside OpenIdConnectAuthenticationNotifications you can capture the error and just move on to the next middleware:
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.Contains("IDX21323"))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
If I can recall, IDS3 requires a nonce but IDS4 does not
I simply updated my Microsoft.Owin.Security.OpenIdConnect package to match the version numbers on my other OWin packages.
Microsoft.Owin [4.1.1]
Microsoft.Owin.Security [4.1.1]
Microsoft.Owin.Security.Cookies [4.1.1]
, and the error was gone.

Attempting to connect to a IdentityServer4 login page fails

I have an existing website that I want to do a proof of concept with OAuth2 / OIDC. To this end I've configured a locally running IdentityServer4 MVC app as my demo OIDC server following the IdentityServer4 quick setup guidelines. This works fine and navigating to:
http://localhost:5000/.well-known/openid-configuration
Lets me see the discovery document.
I have created a fake login page on this OIDC app which consists of just a login button with no user credentials required.
There's no actual user database and I'm just hard coding some user details to return when the 'authentication' occurs.
In my pre-existing site I've added the OWIN middle wear and am configuring OIDC using the OpenIdConnectAuthenticationOptions. The clientId, scopes, secret etc all match as required and the authority is set to point to my locally running demo OIDC app (http://localhost:5000). The redirect url is set to return to my pre-existing site once authentication is complete.
This all appears to be fine but here's what I want to achieve and can't get working. On my pre-existing site when I navigate to any page that requires authentication I want the user to be redirected to the login page I created on OIDC app. They click the login button (no user details required) and are authenticated and redirected back to the original page.
Currently when I navigate to a protected page I am successfully redirected to the OIDC app but I am redirected to an error page and I don't know why. The error page gives me no detail, it's actually hard coded in the app.
When I look at the discovery document I see that the setting for the 'authorization_endpoint' is set to:
http://localhost:5000/connect/authorize
So I thought maybe I needed to either change that to point to Home/Login which is where I've created the dummy login form, or else I needed to actually create that connect/authorize endpoint and put my form there. Creating the end point makes no difference, it never gets hit and instead I just get the error page on my OIDC app. Changing it to home/login also appears to be ignored.
I am away from my main PC at the moment hence the lack of code snippets but essentially the set up is as per the IdentityServer4 quick setup guide and the OIDC app does appear to be working.
The issue is getting my pre-existing site to properly redirect to the login page.
I've been stuck on this for quite a while now and would like to even get to the stage of seeing the dummy login page. Any pointers are appreciated and again apologies for the lack of sample code.
UPDATE
I've got the login form appearing by setting the openidconfiguration like so:
Configuration = new OpenIdConnectConfiguration()
{
AuthorizationEndPoint = "http://localhost:5000/home/login"
}
However, this isn't logging me in when I click login. On that login action I'm doing this:
await HttpContext.SignInAsync("subjectId","username", authenticationProps);
And then redirecting back to my existing site. However it's not authenticating me and the redirect ends up being redirected back again to the login page.
UPDATE 2
I think the redirect URI should possibly be doing something more. Currently I do the following:
Try and access a restricted page -> Redirected to OIDC server -> Click Login (this sets the subject and user successfully) -> Am redirected to redirect URI which immediately bounces me back to the OIDC server.
So maybe the redirect URI is supposed to confirm login or otherwise do something?
So in the open id connect protocol, the authorize endpoint is used to validate the client information passed as query parameters (client_id, scopes, redirect_uri, etc). In your authentication server, none of that is being checked if all the endpoint does is return a form. Then again the validation can be tedious so keeping the authorize endpoint separate from the endpoint for logging in might be worth a thought.
The developers of Identity Server thought the same thing which is why they set up the endpoint (and endpoint validation) for you as part of the middleware. The validation uses the components that were injected (primarily the client_store, and your defined scopes) to be used by Identity Server.
After the framework validates your authorize request using your client store implementation, it will redirect the user to whichever login page you specify. The login page can be specified by changing it with the a delegate that can be passed in as the second parameter of 'AddIdentityServer' (that takes in something of type IdentityServerOptions that we'll refer to as just 'options'). In the delegate you can specify the login url of the page by changing the value of 'options.UserInteraction.LoginUrl' to the url of the login page.
After the user logs in and you call the signInAsync method on the HttpContext, you're actually supposed to redirect back to a query parameter passed to the login page referred to as the 'return_url' (which is basically the initial authorize endpoint request). This authorize endpoint further validates the cookie and will send the user back to the 'redirect_uri' (if consent on the client is set to false) with a code (if using the authorization code flow) or the id_token and optionally the access token (if using the implicit flow).
Assuming the implicit flow for simplicity, the tokens can be found in the request to the 'redirect_uri' and from there it's all up to you. Commonly the client will issue some kind of cookie (which can potentially contain the id or access token) to mark the successful authentication by the identity provider.

Handling LTPA token timeout (websphere 7.x) in JSF richfaces 3.3

I am using JSF richfaces 3.3 on websphere server 7.x.
The problem is when
user logged in to the application using a browser window and had kept it open for more than LTPA token time out time then LTPA token expiration exception is occurring. Then page is not redirecting to the "logout" page configured. But it getting redirected to the Login page and after successful login then a weird xml page is displayed.
I understand that this is happening because on LTPA token time out when we try to access a JSF resource, as no authentication details are present page is being redirected to login page.
Then as no proper session is present Faces context is still trying to access previous session JSF tree this exception is occurring.
So Question is: How to handle this scenario of LTPA token time out in JSF richfaces3.3?
P.S.: Page is getting redirected to "logout" page on web session expiration.
Vamshi,
If the LTPA token has expired and you try to access a secured resource it will naturally take you to the login page.
That is the expected behaviour!
After you login again you go back to the page you had requested. Depending on your app, either a new HTTPSession is created or it might not even be created during this.
The application should be built to handle this. One approach could be to redirect the user to the main page of the application stating that required information is not available and that you are redirecting the user (after examining the HTTP Session for required information)
HTH

Submit Logon form to ASP.NET MVC 2 app from MVC 3 child app - anti-forgery token invalid

I have a parent ASP.NET MVC 2 application at /localhost/app (running in IIS on my dev machine). I can log into this fine from /localhost/app/Account/LogOn. I have a child app (MVC 3) at /localhost/app/childapp. Both apps' web.config have the same machineKey (validationKey/decryptionKey), and if i logon via the parent app, the child app correctly authenticates via the cookie set by the parent app.
What I want is to be able to go to the child app's logon page /localhost/app/childapp/Account/LogOn and post that page to the parent app's logon account controller. However, when I try this, the parent app gives me a server error "A required anti-forgery token was not supplied or was invalid." Given that I have a RequestVerificationToken in both cookie and post, it should be the latter (invalid, vs. not supplied).
Is this just the anti-forgery token doing it's thing, and I can't use that token and post across applications despite sharing the authentication cookie? Or is there a way to make this work? Many thanks!
You could try specifying the domain and path when generating the antiforgery token which will allow the cookie to be automatically sent to the child application:
#Html.AntiForgeryToken(null, "example.com", "/")
Also try inspecting with FireBug the request being sent and see if the cookie is being sent to the child application and if it has the same value as the hidden field.

Resources