How to display UAC prompt for file save to restric

2020-02-28 06:52发布

When a user saves a file from my application, they currently can't save to restricted locations (like C:). I think this is a good restriction, but I would like to provide a UAC prompt to elevate privileges and allow a user to save in a restricted area.

I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.

What I'm wanting to do is basically what Windows itself does. When you try to copy a file to C:\ in Windows 7 (assuming you've got UAC set to its default level), you get the following prompt:

UAC Prompt

Once you click the Continue button with the UAC shield, the file is copied to C:\ with no prompt for credentials (assuming you're logged on with admin privileges).

How can I replicate this behavior in my application for admin users? They shouldn't have to impersonate any other user because they already have admin privileges. Can anyone provide details on what Windows is doing during this process? Are they spawning a new explorer.exe process with elevated privileges?

3条回答
女痞
2楼-- · 2020-02-28 07:22

Programming Elevated Privilege/UAC

Running applications with more privileges than required is against the principle of least privilege, and may have potential security vulnerability. To defend this, Windows Vista introduces User Account Control (UAC), to protect operating system by running applications with reduced privileges (as a normal user), even the current user is signed in as an administrator. More and more XP/2K users are also use normal user account for daily use. Read UAC Demystified first to fully understand UAC.

There are two common mistakes that developers tend to make:

  • Request the end-user to run an application with administrator privilege even though this is not necessary, most of the time because of bad design practices. These applications either scare away end-users, or potentially have security vulnerability.
  • Do not request the end-user to run the application elevated but try to perform operations that require administrator privilege. These applications simply break under Windows Vista or Windows XP/2K normal user account.

The downloadable sample code demonstrates how to programming elevated privilege/UAC. Both WPF and Windows Forms sample applications are provided. Run the application for the following scenarios to see the difference:

  • Normal user, Windows XP/Windows Vista: the UAC shield icon is displayed. Clicking “Save to C:\” displays “Run As” dialog, asking user to enter administrator password to continue;
  • Administrator, Windows XP/Windows Vista with UAC disabled: the UAC shield icon is hidden. Clicking “Save to C:\” completed without any dialog;
  • Administrator, Windows Vista with UAC enabled: the UAC shield icon is displayed. Clicking “Save to C:\” displays dialog asking user’s permission to continue.

Link to Download

Calling the elevated execute (testing for admin first):

private void SaveToRootFolder_Click(object sender, EventArgs e)
    {
        string fileName = @"C:\Test.txt";
        if (App.IsAdmin)
            DoSaveFile(textBox1.Text, textBox2.Text, fileName);
        else
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("Text1", textBox1.Text);
            parameters.Add("Text2", textBox2.Text);
            parameters.Add("FileName", fileName);
            string result = Program.ElevatedExecute(parameters);
            if (!string.IsNullOrEmpty(result))
                MessageBox.Show(result);
        }
    }

Elevated Executes:

internal static string ElevatedExecute(NameValueCollection parameters)
    {
        string tempFile = Path.GetTempFileName();
        File.WriteAllText(tempFile, ConstructQueryString(parameters));

        try
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;
            Uri uri = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
            startInfo.FileName = uri.LocalPath;
            startInfo.Arguments = "\"" + tempFile + "\"";
            startInfo.Verb = "runas";
            Process p = Process.Start(startInfo);
            p.WaitForExit();
            return File.ReadAllText(tempFile);
        }
        catch (Win32Exception exception)
        {
            return exception.Message;
        }
        finally
        {
            File.Delete(tempFile);
        }
    }
查看更多
放荡不羁爱自由
3楼-- · 2020-02-28 07:28

You need to do what Windows does. And spawn a new process which will run with elevated rights. There are no shortcuts here. The token that is allocated when a process starts is what determines what rights the process has. That token cannot be changed after the process has started. If you need to elevate, you need a new process.

I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.

No that's not the case. If the current user is not an admin, then the UAC dialog will prompt for new credentials of a user that does have admin rights. That's the over-the-shoulder UAC dialog. On the other hand, if the current user is an admin then they just get the consent dialog. That's the dialog that's shown on the secure desktop and just asks for you to click Continue.

The one thing that Windows components can do that you cannot is start a process elevated without showing you the consent dialog. That happens on Windows 7 only (not on Vista), and only if you have the UAC setting at the new Default setting that was added in Windows 7. That's how Explorer is able to show the dialog that you included in the question and then start an elevated process to do the copying without showing the consent UAC dialog. Only Windows components are granted that ability.

But the bottom line is that you need to start a new process that runs elevated. Using the runas verb is the canonical way to do it.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-02-28 07:31

A limited option, useful only when Moving, Renaming, Copying, and Deleting files:

SHFileOperation

If you attempt to perform a file operation via this function, Windows will provide the elevation prompt to the user.

Note there are some drawbacks for this:

  • This only works for Moving, Renaming, Copying, and Deleting. Saving a new file this way would require saving to a temp directory, then Moving it to the desired location. This does not solve the problem of the Save File Dialog not allowing you to select a UAC protected location as a target.
  • If the target directory doesn't exist (for a Move or Copy), SHFileOperation can prompt the user if the target directory should be created. However, it will NOT ask for elevated privileges to do so, and so will fail under a UAC protected location. The workaround for this is to manually create the non-existent directories in a temporary location, then Move/Copy them to the target location. This WILL provide the UAC prompt.
  • You need to have contingency plans in place for if the user selects 'Skip' or 'Cancel' to the Move/Copy dialog, or if the user selects 'No' at the UAC prompt.
查看更多
登录 后发表回答