not sure if it's an update but the maximum scale trick doesn't work on iphone. The only thing that works is setting the font-size to anything greater than 16px (16px doesn't work either it has to be greater).
Interestingly, when I initialise a local git repo using vscode built-in tooling, and then try and use gitextensions to view or check-in I get the same problem. It's down to a number of files in the .git folder having some strange owner that's not even an accessible user on my local machine (windows 11 pro, no domain, local account only). Fix is the same, and I prefer to own my files - allthough executables, hooks and anything else I didn't create myself get deleted!
This problem seems to appear on some machines and not others for unknown reasons. We do all our builds with Linux, but it seems to fail more often when using WSL2 (windows subsystem for Linux).
We have this code (Yocto/Openembedded): def define_iv(d): import subprocess source_dir = d.getVar('OEROOT',True) cmd = "git describe" proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, cwd=source_dir) out, err = proc.communicate() return out.decode("utf-8").rstrip()
And it sometimes will return "" instead of the hash if we don't do the "git config --global --add safe.directory ...".
"git describe" for a git repository source will be done many many times during a build. But it will only fail once in a blue moon, which makes me think that git must have bugs.
Started working for me only after I've added the DefaultAuthenticateScheme
DefaultAuthenticateScheme
.AddAuthentication(options => { options.DefaultAuthenticateScheme = "JWT_OR_COOKIE"; options.DefaultScheme = "JWT_OR_COOKIE"; options.DefaultChallengeScheme = "JWT_OR_COOKIE"; })
@Dieter - doesn't that kind of defeat the purpose of a short lived 'one time code'?
Is it possible to also generate some backup codes? A lot of sites also offer this feature if the user is unable to use the Auth app right now.
hi, sometimes I even find this problem after creating the app_offline.html file at the root of the web app, is there a way to programmatically know that the app has been unloaded from the app domain?
I am currently doing a Thread.Sleep for about 20 seconds to make sure the app is unloaded, but this seems like a bad hack!
thanks!
@James - Also in regards of Passkeys I don't like the idea of centralizing everything in the hands of big tech companies. Keys go through Apple, Google, Microsoft and it looks like there's no easy way to interop. If you're using Windows I don't think you can use the Apple tech because there's no way to validate Apple biometrics on Windows.
Spent a bit of time this morning looking around about how this works and it looks the technologies are all open (Fido2 and WebAuthn) but there are few examples that actually go into implementation detail or even on how the auth flow is supposed to work. I suspect the process is very similar to what's use with Authenticators at the end of the day.
But that day is a ways away I'd say. I have not run into any site that uses passkeys yet. And if I do I likely wouldn't think of using because I'd have no idea what it is or how it works - it'll take time even once it becomes regular thing.
@David - Yeah, I know what you mean. I actually thought that it was yet another technology that required some sort of service to provide and validate the validation keys until recently. I ran into a side discussion of how the tech works though to realize that that's not the case - you only need to use a provider for storing the passkeys so they can be shared across devices. In theory you don't even need those as keys can be generated by algorithm - as long as you can keep the key present.
@James - and that leads right into your point, which is that Passkeys are very similar in the way they work to the way Authenticators work. I think they actually use the same protocols. The difference is that instead of using a service to host your public keys your device becomes the key store. I suspect you're right in the future that will be the better choice but right now that tech is not widely supported, and it ties the keys to the provider (ie. right now Apple, Google, Microsoft).
Functionally though the technology is similar - both use single use passkeys that are only good for short time intervals.
Thank you, awesome guide, just save my life 19/05/2023 Maybe not my life but my mental health 😉
I do and have for many years appreciate Ricks amazing contributions to the .net community and have often been a beneficiary of his advice.
I would however recommend skipping implementation of authenticators now and moving straight on to passkeys for anyone reading this.
There is an also somewhat technical implementation issue in Brandon’s code which although shouldn’t present a security risk to the average user does lower the entropy of the random number used to create the shared secret.
This is one of my favorite reasons to read your blog: super-thorough research! I really never understood how 2FA could be implemented with an Authenticator app by a "regular developer", but now I'm really hoping to get a project where I can try this out.
Thanks for this guide. It helped me resolve the exact same issue in my development environment.
This really helped me. In my situation, I was trying to call a URL on the same server as the calling (the httpClient) code. At first, authentication failed -- actually, it was never attempted. IIS logs showed that the credentials were never passed at all, and I could not figure out why. I believe it was ultimately caused by loop back protection on the server running the endpoint I was trying to reach with httpClient. This can be disabled with a registry key, but since I didn't want to modify my endpoint server's registry, so I ran my httpClient code on another machine in the same network and it worked perfectly. I can confirm that using CredentialCache.DefaultNetworkCredentials worked fine for me, since my calling code was running in a user context that was authorized to access the endpoint server I'm running the calling code in a scheduled job with a certain user credential configured for the scheduled job. Good luck and thanks Rick!
CredentialCache.DefaultNetworkCredentials
@James - good catch, I didn't notice. I took a look and it appears that recent versions of ASP.NET have changed when the headers are injected by the ASP.NET Core framework. It appears the headers are now injected after all the processing is completed. I took a look and set it breakpoint inside of the 1) the MVC request handler, and 2) inside of the middleware and neither one of them shows the ASP.NET generated headers in Response.Headers - only those that the application is adding. Can't remove headers that aren't already present.
Response.Headers
So the remove functionality is somewhat broken in the middleware handler - that may no longer be possible to do.
I've removed the remove operations from the sample.
remove
In the post you have '''opt.HeadersToRemove.Add("X-Powered-By");'''
but the screenshot shows the X-Powered-By header. Assuming that's a mistake?
@James - thanks for the reminder - I've added a note into the post.
The web.config removal works as long as the app is running on IIS 10+.
Check out: EFCore.BulkExtensions
Thanks for great article (and another even better about combining cookie and jwt)! I wanted though to implement additional 'Secondary layer' for fwt tokens - when user account is disabled by admin, check its state in database and forbid access. For cookie authentication there is article how to inject such procedure https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1#react-to-back-end-changes-1 but I can't find similar way for fwt tokens. Can you give a hint on implementation (a link maybe)?
First I would just never send any email with an attachment. Even if gmail/outlook don't block it, we find there are a lot of other things out there companies use that will. And if you look at it from a company's perspective - they don't want to be a victim of ransomware. So it's completely understandable.
What we have found that works, is:
Create a $5 digital ocean droplet and point a domain at it, e.g., files.contoso.com. Create a directory called /files.
Set up apache like this (assuming cloudflare is adding the HTTPS):
<Directory /files> Options -Indexes Require all granted </Directory> <VirtualHost *:80> ServerName files.contoso.com DocumentRoot /files </VirtualHost>
You may be able to send a link out to https://files.contoso.com/myprogram.exe although we have found those cause emails to get blocked as well.
You might have more luck with a link to https://files.contoso.com/myprogram.zip but who wants to force a user to unzip things?
If you send a URL out like https://files.contoso.com/funkyurl and in the response you redirect to an EXE we have also found that they get blocked - email servers are smart enough to follow links and see if it results in the dropping of a file!
The 100% most reliable way we have found to send links to executables is to send a link to a pure HTML page and on that, embed the link to the EXE which the user clicks on.
Then, they only have to contend with their browser trying to quarantine the file! But if they can get around that, at least they can then run the setup EXE without any further steps!
Rik thanks for 20 years of great content!
@Thomas - the reason I think the .b64 is preferrable is that you can use 7Zip with the file. In either situation you need some sort of tooling or script to create the .b64 or rename a file. With the .b64 you may only need it on the sending side as 7Zip can handle the receiving end.
.b64
Probably a right-click context menu item that add/removes .txt at the end (or creates a copy when it goes from .docx to .docx.txt, and then just renames going the other way). Much easier to do manually if the recipient (or you on another computer) doesn't have the tool installed.
@Viliam - unfortunately not. If the .7z file is encrypted at all with file names hidden, GMail will not let it go.
.7z
What about checking "Also encrypt filenames" when encrypting zip/7zip files?
Thank you for the solution. for me the user agent check for iphone worked like a charm in both android and ios devices
.Net 8 should bring some improvements in this area. https://devblogs.microsoft.com/dotnet/announcing-dotnet-8-preview-3/#simplified-output-path
@Alik - I'm not sending this - the browser is when making the request in JSON calls. ASP.NET Core decides how to send back the data and it may send it all at once or send partial responses that correspond to the Expect 100.
Expect 100
Frankly I don't know how those semantics work - it happens behind the scenes, and it's not something that you have to manage with your API code, unless you explicitly set options on the API configuration.
Hi I notice you are sending Expect 100 continue. I have some issues understanding this. For example, lets say I have a API Method Called GetData. And I am asked to send back 100 status code. I tried this and the caller just hangs even when using return StatusCode(100,"Hi"). But according to all your samples you don't handle or return the Except 100continue just send it as a header. Am I missing something?
@David - I self host a Windows Server on a VPC server I manage (on Vultr). Performance and price is excellent and I run 30+ sites on this server.
Thank you, this is the article I was looking for. Btw may I know what you use for your great and fast website? I'm also planning to create a simple website for my business, but I need a domain and hosting recommendation. I hear asphostportal has a good reputation for that. Can you recommend them or are there any alternatives?
I did not have the same amount of trouble as you did. I created a simple .net application on 4.7.1, and added the manifest, as described here: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
Everything works fine when I'm using System.IO.Directory and such.
Use:
endpoints.MapFallbackToFile("{**path}", "/index.html");
By default, MapFallbackToFile("/index.html") acts like endpoints.MapFallbackToFile("{**path:nonfile}", "/index.html").
MapFallbackToFile("/index.html")
endpoints.MapFallbackToFile("{**path:nonfile}", "/index.html")
For me work:
$('.modal').on('shown.bs.modal', function() { $('.modal-backdrop').addClass('show'); })
$('.modal').on('hidden.bs.modal', function() { $('.modal-backdrop').removeClass('show'); //this $('.modal-backdrop').remove(); //or })
@Tony - already addressed in the Summary at the end of the post...
I do support that (Print option, which includes the Save As Pdf) but it has other issues - namely no PDF TOC and sloppy handling of page breaks (orpahaning).
Why not use the print to PDF functionality that is built into WebView2?
Wouldn’t this be a better solution, since the rendering engine would be evergreen (or a fixed version depending on how you embed WebView2) and you wouldn't have to bundle anything extra (or a small redistributable in the case of a fixed version)?
Thanks for this Rick. Like you, I couldn't find any documentation on the subject - so thanks again for sharing it with us.
@R - Yes and no. I've used PanDoc and it sort of works, but is pretty limited in control over the output.
The main issue with these solutions is that I need to be able to bundle it with my application. Requiring a huge install of PanDoc or Python is not really an option. WkHtmlToPdf isn't small either, but at least it's self-contained and easy to bundle alongside an existing application.
I've looked at some of the third party solutions and redistributable rights on most of these are prohibitively expensive - I can't justify spending thousands of dollars for a small sub-feature in a niche product that doesn't exactly make a fortune 😄
Have you tried the alternatives that wkhtmltopdf recommend? (WeasyPrint)
Did you consider using Pandoc?
@Ashley - tell us how you really feel.
Buttons and links are different UI elements and I'm all for using a button when a button is appropriate. If it's not styling a button like a link is hardly the right thing to do, don't you think? As said, styling a button to look like a link requires a ton of settings - maybe it's lazy duplicating all that, but it sure as shit is bound to be an accessibility nightmare as well to get proper link behavior (and very likely to get it wrong if you do it from scratch).
You can't have it both ways.
Rick, Like many of your posts, this is a brilliant and very helpful post. You have saved the day for me! Many thanks.
Had the same problem as you a while back, also sad about WkHtmlToPdf demise. But luckily I had the problem on the server side - there with rendering mails to PDF (I come from document management).
As you mentioned I also use Chromium's Save to PDF functionality by utilizing the Pupetteer API inside a docker container. But I guess that is not an option for you...
QuickPdf (now bought by foxit) used to be a good reasonable priced alternative for 300-900 Dollars, but just saw they increased prices dramatically.
Thanks for the secret incantation: \? It worked when nothing else did.
@Hellman - yes you can run older version compiled packages and assemblies in a later version of .NET Core. If you add a reference you can add any .NET assembly really, including full framework as long as you're not using functionality that is no longer available in the new framework.
This is a great article thank you for all the details. I have a twist on the topic which I haven't found addressed anywhere else. Can a .net 6 application reference an older .net core assembly (say core 3.0) and run on a machine with only .net 6 runtime? From my limited testing I have proven this is possible, but there maybe cases this doesn't work for.
You could also simplify even more your life with the following command:
git config --global --add safe.directory '*'
or via the .gitconfig file:
[safe] directory = *
which tells git that all your repositories are safe. This works with version Git for Windows 2.35.3 and more recent versions.
Rick gets it... I have no idea why .net compiler doesn't have an error system in place that you are using the old api with MAX_PATH and have the long path support enabled by default.. this way I feel like, you will even be forced to not use this limited api...
same goes for all other new applications.. just make it so we can move on eventually from this 260 nonsense... maybe another 20 years
if you read this in 2043 then microsoft is just awful
I normally don't leave comments, but man, thanks so much for this article. It saved me a lot of time and headaches, you are a legend!
Great article. Floundering on a bug and came across this post. Struggling with redirect to "path", "./path", "/path", or "~/path".
I started to write the full description/question here, but then realized maybe I should put it on stackoverflow. If you see this comment and have the time, I've posted my question at:
https://stackoverflow.com/questions/75510599/net-core-response-redirect-works-in-development-but-not-on-iis-usage-includ
Thanks
I'm glad to see you blogging more again Rik.
Your content is always super useful