FileIOPermission checks code permissions under the .NET Code Access Security model, not user permissions in the Windows file system. Since your code runs under an admin account, the code presumably has adequate FileIOPermission, so it is unsurprising that the demand passes when running under a different user account.
Since the demand for FileIOPermission does pass, the code attempts to save the file, which is when it runs into insufficient user permissions in the non-admin scenario. UnauthorizedAccessException is the expected exception type when the operating system denies access to the target resource.