I do have a Blazor WASM (.NET 6) application that is using an Identity Server hosted on different URL for authentication.
I'm configuring the authentication like this:
builder.Services.AddOidcAuthentication(options =>
{
options.ProviderOptions.Authority = configuration.OidcAuthority;
options.ProviderOptions.ClientId = configuration.OidcClientId;
options.ProviderOptions.ResponseType = configuration.OidcResponseType;
options.ProviderOptions.PostLogoutRedirectUri = configuration.OidcPostLogoutRedirectUri;
options.ProviderOptions.RedirectUri = configuration.OidcRedirectUri;
options.ProviderOptions.DefaultScopes = configuration.DefaultScopes;
});
Everything works great locally and in production as well.
The problem occurs when I want to open the page in Chrome Incognito window with Third party cookies disabled.
I see in the browser that during authorization process I receive cookies with SameSite=None and Secure=true, but this cookie is not send with
https://login.myidserver.net/connect/authorize?client_id=myclientid&redirect_uri=h...
as oppose to normal Chrome window.
Because of that I receive back
https://localhost:12345/authentication/login-callback?error=login_required&state=....
and access_token is not saved in session storage as it should be.
Is there any way to overcome this and force the cookie to be used in this case?
Or am I misunderstanding something?
All the solutions I've seen on the internet seems not to work for me.
Edit:
Ok, why is authorize called right after sucessful authentication and receiving of the token?. I understand I cannot force to send this cookie but can I somehow avoid do this authorize call when I'm right after successful login?
I'm using this code to try to get the auth from Google:
await HttpContext.ChallengeAsync("Google", new AuthenticationProperties() {RedirectUri = "/"});
The thing is the redirect always take the HTTP url even if I'm running it from https url.
The url with https://something-sss.com is already whitelisted on the GCP API identifiers.
But it always take the Uri with http
To expose my docker app I used to use Expose http://*:80 and even if the associated domain was started with an HTTPS, inside the app it was always an HTTP call, so all the redirects were done through the http protocol.
I have changed the way I expose my app from http://*:80 to https://*:443 in the code I used kestrel to launch the app and it's working perfectly now.
I have an application using the OWIN middleware for OpenIdConnect. The startup.cs file uses the standard implementation of app.UseOpenIdConnectAuthentication. The cookie is set to the browser, but it errors with:
IDX10311: RequireNonce is 'true' (default) but validationContext.Nonce is null. A nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'.
I've found that when running fiddler as I do for most debug projects this behavior happens. The error is returned, but if I go back to the site everything is working and my user is authenticated. Has anyone seen this behavior when running fiddler?
With fiddler:
SecurityTokenValidated notification in OpenIdConnect is executed twice.
After the second pass through the IDX10311 error is thrown
Browser contains the valid cookie, going back to the page I can view the valid User.Identity data.
Running without fiddler:
SecurityTokenValidated executes once in OpenIdConnect
No error thrown, proceeds to load up controller action for post authentication redirect Uri
Cookie also valid and User.Identity data correct.
Ideas? I can get around it without running fiddler, but when debugging it would be nice to also run fiddler to inspect traffic.
Maybe is this the cause?
Hello there, I think I found the root cause of this issue.
I'm summing up my discoveries:
The problem is in the OpenIdConnect.nonce.OpenIdConnect cookie
This cookie is set from the app (let's call this "ID Client") as soon as the OpenID Middleware init an authentication session
The cookie should be sent back from the browser to the "ID Client" as soon as the authentication has been completed. My assumption is that this cookie is needed to have a double check from the ID client point of view (i.e. did I really started an OpenID Connect authorization flow?)
A lot of confusion in me was caused by the "Nonce" term, used both in this cookie and in the OpenID Connect flow from the ID server.
The exception, in my case, was caused by the missing cookie (not the nonce of the ID Server), simply because it wasn't sent by the browser back to the "ID client"
So the main root, in my case, was this: OpenIdConnect.nonce.OpenIdConnect cookie was not sent back to the ID Client by the browser. In some cases (i.e. Chrome, Firefox and Edge) cookie was sent correctly, while in others (IE11, Safari) it wasn't.
After a lot of research, I discovered that the problem was on the Cookie restriction policy, defined on the browser. In my case, the "ID client" is embedded in an <iframe>. This cause the "ID Client" to be seen as a "third-party client", because the user didn't navigate to that URL directly in the main window. Because this is a third-party, for some browsers, it's cookies have to be blocked.
Indeed the same effect may be obtained on Chrome, by setting "Block third-party cookies".
So, I have to conclude that:
a) If iframe is a must (as in my case, because "ID Clients" are apps that must run inside the graphic content of the our main platform app), I think the only solution is to intercept the error, and handle it with a page, asking the user to enable third party cookies.
b) If iframe is not a must, it should suffice opening the "ID Client" in a new window.
Hope this helps somebody, because I got crazy!
Marco
I had the same problem but switching back the Microsoft.Owin.Security.OpenIdConnect to version 3.0.1 solved the issue
For anyone else who gets here in 2021, you'll likely get this issue if:
You're redirecting http -> https
Or you've changed your app's host domain.
Both of these aren't an issue with the middleware or your app, but it's about the combination of two issues:
The fact that your app is still hosted on the old old domain or protocol. You want to prevent browsers hitting that by implementing a redirect on the web server.
The redirect URI (sometimes know as reply URL) in Azure or whichever OpenIdConnect authorization server you're authenticating with. You want to get this updated to the new protocol or domain.
Our example: We had https://old.example.com/app/ that was now also hosted at https://new.example.com/app/. We wanted users' previous bookmarks to still work.
Our solution:
We updated the redirect URI (reply url) to point to the new domain for the app (https://new.example.com/app/signin-endpoint). Ideally, make sure there is only one URI listed for your app and that it's https.
We added the new domain binding to the site in IIS (we're old school, but do the same for your hosting of choice 😊)
We added an IIS redirect to the new domain (new.example.com) so that users' bookmarks still work. Again if you're not on IIS, implement a permanent redirect in the web server of your choice.
Until we had the final step above, we were seeing the error in the OP's post. It's the same process if you're forcing http -> https.
Here is the IIS re-write for those who are also "old school":
<rewrite>
<rules>
<rule name="Redirect old.example.com to new.example.com" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions>
<add input="{HTTP_HOST}" pattern="old.example.com" />
</conditions>
<action type="Redirect" url="https://new.example.com{REQUEST_URI}" />
</rule>
</rules>
</rewrite>
It goes in the <system.webServer> section of your web.config file. Enjoy!
For me changing reply url in Azure active directory works.
This happens when you enable SSL because it changes only the sign on URL to the HTTPS URL while the reply URL remains the same HTTP URL.
When you try to access your app using the https URL, it sets a cookie with a unique number(nonce) in your browser and hits Azure AD for authentication. After authentication, the browser has to give access to that cookie. But since the sign on URL and reply URL are different the browser does not recognize your app and does not give access to that cookie and hence the application throws this error.
I know its an old post but I had this problem and nothing was working for me, after lose my mind behind a solution to make my enterprise application works I end up fixing it by setting the multi-tenanted option to yes in azure (in Azure select: app registration>settings>properties, set multi-tenanted to yes and click save).
hope it helps someone, couldn't see nobody mentioning it.
I noticed this error when running IIS Express in the background when I had switched to hosting in full IIS. When I disabled the IIS Express, my error went away.
A cookies rewrite rule in the web.config to ensure samesite cookies gave this cryptic exception. Disabling that rule solved it.
A temporary solution which worked for me for an app secured via Azure Active Directory was to signout (by going to the sites/Account/SignOut page) and then I was able to return to the home page and sign in ok. Hope this helps someone.
I know it's been a while on this one. My specific issue was with the IDX10311 error in relation to authenticating with IdentityServer while Fiddler (traffic inspector proxy) was running. I added a custom owin middleware to catch and absorb the IDX13011 in the case where the hostname contained "localhost". Ignoring this exception allowed us to use the site with fiddler as a workaround. I think it causes breaks in the authentication process though where we have to press enter in the browser address bar on the callbacks to get it going again, but this only affects development.
Here's the invoke method we used in the middleware to absorb the error. I should note though that we have seen this error in production occasionally as well. No explanation for a cause, but I have a feeling it is related to users on IE browsers.
public override async Task Invoke(IOwinContext context) {
try {
await Next.Invoke(context);
} catch (Exception ex) {
_errorHandling = new ErrorHandling();
if (ex.Message.Contains("IDX10803")) {
//do something here to alert your IT staff to a possible IdSvr outage
context.Response.Redirect("/Error/IdSvrDown?message=" + ex.Message);
} else if(ex.Message.Contains("IDX10311") && context.Request.Host.Value.Contains("localhost")) {
//absorb exception and allow middleware to continue
} else {
context.Response.Redirect("/Error/OwinMiddlewareError?exMsg=" + ex.Message + "&owinContextName=" + lastMiddlewareTypeName);
}
}
}
For me it was a different problem. My site was working with both of the urls below
https://www.example.com
and
https://example.com
But my redirect url was https://www.example.com.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = ConfigurationManager.AppSettings["ClientId"].ToString(),
Authority = ConfigurationManager.AppSettings["Authority"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectUri"].ToString();//https://www.example.com
}
Users who use https://example.com the mentioned exception occurs.
The cookie generated for www.example.com and example.com are different. So after the login when it redirects, the cookie doesn't contain the correct nonce to validate and the exception occurs.
The solution for the problem is to set the redirect URL dynamically
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = ConfigurationManager.AppSettings["ClientId"].ToString(),
Authority = ConfigurationManager.AppSettings["Authority"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectUri"].ToString(),//https://www.example.com
,
// sample how to access token on form (when adding the token response type)
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = async n =>
{
var uri = n.Request.Uri; //From request URL determine the RedirctUri and set below
n.ProtocolMessage.RedirectUri =""//Set the url here
}
}
}
The same issue can happen with https://www.example.com and http://www.example.com
Users where getting this issue when Edge was set to IE compatibility mode, removed it from IE compatibility and it solved the issue. Setting / list of sites is controlled under edge://compat.
I end up allowing the Owin to skip to the next Middleware on AuthentificationFaild callback function. I'm checking if the error message contains nonce error Id and call SkipToNextMiddleware function from the context. With that, I'm restarting the sign-in process so if the user cookies were not set there will be a second call that will set the cookie.
The code is written in vb.net
Dim oidcAuthOpt= New OpenIdConnectAuthenticationOptions()
oidcAuthOpt.Notifications = New OpenIdConnectAuthenticationNotifications With {
.AuthenticationFailed = Function(n)
If (n.Exception.Message.StartsWith("OICE_20004") Or n.Exception.Message.Contains("IDX10311")) Then
n.SkipToNextMiddleware()
Return Task.FromResult(0)
End If
Return Task.FromResult(0)
End Function
}
I needed to support, in addition to standard out-of-the-box cookies/forms authentication, also Basic Authentication over HTTPS for SignalR. SignalR runs in the context of a mixed MVC/WebApi site.
After putting the pieces together how to implement this, I used ThinkTecture.IdentityModel.Owin.BasicAuthentication library for this on the server, like this:
app.Map("/basicauth", map =>
{
map.UseBasicAuthentication("realm", ValidateUser);
map.MapSignalR<AuthenticatedEchoConnection>("/echo");
map.MapSignalR();
});
But instead of returning a challenge, I always get a HTTP 302 response that redirects to the Login page of the MVC site. To better debug this, I quickly rolled my own simple OWIN middleware for basic authentication and got the same result. Further testing with a simple mapping like this:
app.Map("/test", map =>
{
map.Use((context, next) =>
{
// context.Response.StatusCode = 401;
context.Response.Write("Hello World!");
return Task.FromResult(0);
});
revealed that a simple "Hello World" response is returned normally. But when I comment out the the line that sets the response code to 401, I get the redirect to the Login page again. I do not understand this behavior ... why does my MVC site gets involved here and not the 401 response is returned? How can I prevent this?
For OWIN, besides the special /basicauth map above, I had only the top level SignalR mapping in the startup method defined that should continue to work for all cookie authenticated calls:
app.MapSignalR();
Nothing else had been configured by me for OWIN.
Can anybody help me with this?
Ok, I found a way to work around this issue. The first part is to throw out map.MapSignalR<AuthenticatedEchoConnection>("/echo"); from the first sample - it is not necessary and for some reason I not found out it prevented SignalR from working properly.
The second part, and the workaround for the actual problem, is that in the client I also send the credentials with the first request and do not wait for a challenge. Thus, a 401 never happens and so no redirect to login page. And that's good enough for me.
So the workaround is, in the client, do not use NetworkCredential like this:
connection.Credentials = new NetworkCredential(username, password);
Instead, add the Authorization header yourself so it is included already in the first request:
string creds = string.format("{0}:{1}", username, password);
string encodedCreds = Convert.ToBase64String(Encoding.Utf8.GetBytes(creds));
connection.Headers.Add("Authorization", "Basic " + encodedCreds);
In addition, what I found out is that with OWIN, this issue seems to be a more general one and not only related when used with SignalR or even Basic Auth:
http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
Thus, with some modifications to the basic authentication module, it should also be possible to prevent this redirection. I might look into this and will update this post when done.
I have a asp.net mvc 4.0 web application that attempts to use windows authentication to authenticate against some web services. its hosted in iis7
The web services are autodesk vault 2011 web services, I present the user with a login screen where they can use a vault user account or they can use their windows login. There is no issue with using a vault account it logs in via the vault web services and call the various vault web services such as pulling data out of the vault. no issues here
When trying to log in using windows authentication then I get a 401 error when accessing the web services
I think that it could be a double hop issue so the server admins are going to enable Kerberos so we can at least eliminate this as a possibility. In the live environment the site and web services are located on different servers.
However for testing I have a virtual machine setup and the site and web services are on the same machine and I still get a 401 issue so maybe it is an iis configuration issue and not a double hop issue as originally thought
I have tried the following but with no success
I have added the following code to the winauthservice (I have wrapped the web services so that I can override the invoke and I have created a factory class to instantiate the services)
this.UnsafeAuthenticatedConnectionSharing = true;
var credentialCache = new CredentialCache();
credentialCache.Add(new Uri(this.Url), "NTLM", new NetworkCredential(identity.Name, identity.Password.ConvertToUNSecureString(), identity.Name.Substring(0, identity.Name.IndexOf("\\", StringComparison.OrdinalIgnoreCase))));
this.Credentials = credentialCache;
I have also tried it with Negotiate instead of NTLM
I have disabled the loopback check in the registry and I have added the server name and localhost to the BackConnectionHostNames registry entry
I have disabled anonymous authentication for the web site in iis and enabled windows authentication. In the providers for windows authentication I have removed negotiate and just left NTLM as saw a post recommending to do this.
In the web.config I have set authentication mode = windows
I have the following in my IIS logs
2013-09-25 09:11:05 fe80::9565:6102:fe2d:8f41%10 POST /AutodeskDM/Services/WinAuth/WinAuthService.asmx - 80 - fe80::9565:6102:fe2d:8f41%10 Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+4.0.30319.296) 401 2 5 11572
2013-09-25 09:11:05 fe80::9565:6102:fe2d:8f41%10 POST /AutodeskDM/Services/WinAuth/WinAuthService.asmx - 80 - fe80::9565:6102:fe2d:8f41%10 Mozilla/4.0+(compatible;+MSIE+6.0;+MS+Web+Services+Client+Protocol+4.0.30319.296) 401 1 3221225581 10
I'm running out of ideas as to what the issue could now be, but my thought is if I can get this working in my test vm then I may have more luck in the live environment
I had problems with authentication surviving a redirect when using a HttpWebRequest object, but I'm not sure if this is your problem. I noticed the redirect and the missing authentication using Fiddler2.
What I had to do was to set PreAuthenticate = true on the HttpWebRequest object
HttpWebRequest request;
request = (HttpWebRequest)WebRequest.Create(uri);
request.PreAuthenticate = true;
request.Credentials = new CredentialCache {{uri, "Basic", credentials}};
But, like I said, I'm not sure if this applies in your situation though.