简体   繁体   English

MSIX Windows 10 应用程序访问被拒绝后 SSO 登录 Azure 迁移

[英]MSIX Windows 10 App Access Denied post-SSO sign-in for Azure migiration

We are in the process of migrating our applications into Azure.我们正在将我们的应用程序迁移到 Azure 中。

We have created an MSIX installer for an internal WPF application that installs to the Windows 10 C:\Program Files\WindowsApps\ folder.我们为内部 WPF 应用程序创建了一个 MSIX 安装程序,该应用程序安装到 Windows 10 C:\Program Files\WindowsApps\文件夹。 When we run the application, it requires us to enter our Single Sign-On (SSO) credentials via the online Windows/Azure web portal.当我们运行应用程序时,它要求我们通过在线 Windows/Azure web 门户输入单点登录 (SSO) 凭据。 After successfully entering our credentials, we get a following pop-up that says access to a file is denied (see below).成功输入我们的凭据后,我们会收到以下弹出窗口,提示访问文件被拒绝(见下文)。 We get this error regardless of whether running it normally or as administrator .无论是正常运行还是as administrator运行,我们都会收到此错误。

We are unable to find anything online that has been helpful in resolving the error.我们无法在网上找到任何有助于解决错误的内容。 We did try taking ownership of this protected folder and then unchecking the read-only option, but that did not work (nor does that sound like a good idea, but this is troubleshooting).我们确实尝试获取此受保护文件夹的所有权,然后取消选中只读选项,但这不起作用(这听起来也不是一个好主意,但这是故障排除)。 We do not see anything in the MSIX setup project that can resolve this issue.我们在 MSIX 安装项目中看不到任何可以解决此问题的内容。 Does anyone know why we are getting this error and how to resolve it?有谁知道我们为什么会收到这个错误以及如何解决它?

错误消息框

In the Event Viewer, the following information is provided:在事件查看器中,提供了以下信息:

事件查看器错误详细信息

MSIX-packaged apps do not support write access to files from the installation folder (WindowsApps). MSIX 打包的应用不支持对安装文件夹 (WindowsApps) 中的文件进行写入访问 This is by design, taking ownership and forcing file changes is not allowed by the OS.这是设计使然,操作系统不允许获取所有权和强制更改文件。

Any configuration files that need to change (get updated) when the application is running should be saved either in the AppData user folder, or the CommonApplicationData machine folder (if multiple users need access to this config/file).应用程序运行时需要更改(更新)的任何配置文件都应保存在 AppData 用户文件夹或 CommonApplicationData 机器文件夹中(如果多个用户需要访问此配置/文件)。

I've already written a longer explanation on this topic here:我已经在这里写了关于这个主题的更长的解释:

PS Saving user-data files in the installation folder is, generically speaking, a bad practice, even if you don't deploy your application using an MSIX. PS 在安装文件夹中保存用户数据文件一般来说是一种不好的做法,即使您不使用 MSIX 部署应用程序也是如此。 A logical separation between application files and application data (configs, user data, etc...) helps ensuring your customers can smoothly upgrade your app without losing their data/configs, can easily migrate to a new PC if the old one crashes, can run the app in virtual environments (enterprise clients) and you get fewer headaches over support;).应用程序文件和应用程序数据(配置、用户数据等)之间的逻辑分离有助于确保您的客户可以在不丢失数据/配置的情况下顺利升级您的应用程序,如果旧 PC 崩溃,可以轻松迁移到新 PC,可以在虚拟环境(企业客户端)中运行应用程序,您对支持的头痛就会减少;)。

We are unable to find anything online that has been helpful in resolving the error.我们无法在网上找到任何有助于解决错误的内容。

From the docs that lists the things you need to know before you convert your existing installer into an MSIX :列出在将现有安装程序转换为 MSIX 之前需要了解的事项文档中:

Your application writes to the install directory for your app.您的应用程序将写入您的应用程序的安装目录。 For example, your application writes to a log file that you put in the same directory as your exe.例如,您的应用程序写入与您的 exe 位于同一目录中的日志文件。 This isn't supported because the folder is protected.不支持此操作,因为该文件夹受保护。 We recommend writing to another location like the local app data store.我们建议写入其他位置,例如本地应用程序数据存储。 We have added a capability that allows this in 1809 and later.我们在 1809 及更高版本中添加了允许此操作的功能。

The solution is obviously to save the file in another folder where to which your app does have write permissions.解决方案显然是将文件保存在您的应用程序确实具有写入权限的另一个文件夹中。 An MSIX packaged app never has access to write files to the installation folder. MSIX 打包应用永远无权将文件写入安装文件夹。

I found the problem - it was the need to store the token in a cache file.我发现了问题 - 需要将令牌存储在缓存文件中。 When I did a Google search for msalcache , it came back as the TokenCacheHelper , which is in the stack trace.当我在 Google 上搜索msalcache时,它以TokenCacheHelper的形式返回,它位于堆栈跟踪中。 This file appears to be auto-generated with the code output below.该文件似乎是使用下面的代码 output 自动生成的。

//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation.
// All rights reserved.
//
// This code is licensed under the MIT License.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//------------------------------------------------------------------------------

using Microsoft.Identity.Client;
using System.IO;
using System.Runtime.Versioning;
using System.Security.Cryptography;

namespace <AppName>.Helpers
{
    static class TokenCacheHelper
    {
        /// <summary>
        /// Path to the token cache
        /// </summary>
        public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3";

        private static readonly object FileLock = new object();

        public static void BeforeAccessNotification(TokenCacheNotificationArgs args)
        {
            lock (FileLock)
            {
                args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath)
                        ? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath),
                                                 null,
                                                 DataProtectionScope.CurrentUser)
                        : null);
            }
        }

        public static void AfterAccessNotification(TokenCacheNotificationArgs args)
        {
            // if the access operation resulted in a cache update
            if (args.HasStateChanged)
            {
                lock (FileLock)
                {
                    // reflect changesgs in the persistent store
                    File.WriteAllBytes(CacheFilePath,
                                       ProtectedData.Protect(args.TokenCache.SerializeMsalV3(),
                                                             null,
                                                             DataProtectionScope.CurrentUser)
                                      );
                }
            }
        }

        internal static void EnableSerialization(ITokenCache tokenCache)
        {
            tokenCache.SetBeforeAccess(BeforeAccessNotification);
            tokenCache.SetAfterAccess(AfterAccessNotification);
        }
    }
}

After doing some more searching, I found these two links of relevance:在做了一些搜索之后,我发现了这两个相关的链接:

The relevant code in question is for the CacheFilePath , which is actually stored in a comment:有问题的相关代码用于CacheFilePath ,它实际上存储在注释中:

/// <summary>
/// Path to the token cache. Note that this could be something different for instance for MSIX applications:
/// private static readonly string CacheFilePath =
/// $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\{AppName}\msalcache.bin";
/// </summary>
public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3";

The recommended fix for the CacheFilePath is actually invalid. CacheFilePath的推荐修复实际上是无效的。 So, I made the following modification:所以,我做了以下修改:

private static readonly string AppName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
private static readonly string ApplicationDataFolder = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\{AppName}\\";
private static readonly string CacheFilePath = $"{ApplicationDataFolder}\\msalcache.bin";

I then added the following method:然后我添加了以下方法:

public static void CreateApplicationDataDirectory()
{
    FileInfo fileInfo = new FileInfo(ApplicationDataFolder);

    // Check to see if the directory exists. If it does not then create it. If we do not do this then the token CacheFilePath will
    // not be created.
    if (!fileInfo.Exists)
        Directory.CreateDirectory(fileInfo.Directory.FullName);
}

I then modified the App.Xaml.cs file to call the CreateApplicationDataDirectory right after the ApplicationBuild process:然后我修改了App.Xaml.cs文件以在ApplicationBuild过程之后立即调用CreateApplicationDataDirectory

_clientApp = PublicClientApplicationBuilder.Create(Params.ClientId)
            .WithAuthority(AzureCloudInstance.AzurePublic, Params.Tenant)
            .WithRedirectUri("http://localhost:1234")
            .Build();
TokenCacheHelper.CreateApplicationDataDirectory();
TokenCacheHelper.EnableSerialization(_clientApp.UserTokenCache);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MSIX 安装的 WPF 应用程序使用 Azure SSO 将无法启动 - MSIX Installed WPF application that uses Azure SSO will not launch 如何从 WPF MSIX 应用程序(桌面桥)更改 Windows 10 Colors 设置? - How can I change the Windows 10 Colors settings from a WPF MSIX app (Desktop Bridge)? MSIX 打包的 WPF 应用程序阻止了 windows 的多个实例? - MSIX packaged WPF app that prevent multiple instances of windows? 在Windows 10中访问c:\\ Programdata中的文件时访问被拒绝 - Access denied while accessing files in c:\Programdata in Windows 10 Windows 10 通用应用程序文件/目录访问 - Windows 10 Universal App File/Directory Access 当用户被拒绝访问AppData(漫游)文件夹时,SQL Server Compact 4.0无法在Windows 7上运行,但仍可以在Windows 10上运行 - When Users Are Denied Access To AppData (Roaming) Folder, SQL Server Compact 4.0 Cannot Work On Windows 7 But Can Still Work In Windows 10 由于未注册Windows.Launch合同,Windows 10分配的访问应用程序无法启动 - Windows 10 assigned access app fails to start due to not registered for Windows.Launch contract 使用WPF创建Windows 10应用 - create windows 10 app with wpf Windows Azure Access Control和WPF? - Windows Azure Access Control & WPF? Windows窗体或WPF桌面应用程序通过MFA登录到Azure AD以访问Web API - Windows Forms or WPF Desktop App logging in to azure AD with MFA to access web api
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM