1

I'm looking to build a proof of concept / demo webpage that will:

  • Run as a service (no authentication required initially)
  • Prompt for credentials (i.e. to allow providing alternate credentials, ideally capture this as System.Management.Automation.PSCredential). No authentication is required here, I just need to capture the credentials.
  • Pass credentials in to PowerShell (e.g. shell.Commands.AddArgument(pscred) )
  • Use these credentials in PowerShell (pass in as, or convert to System.Management.Automation.PSCredential)
  • To clarify: I do not want to authenticate credentials. I just want to collect them in a secure way. For all I care at the moment, it is gibberish, but gibberish that I presumably want to protect

I have an ASP.NET Web Application project with Visual C# (similar to the one here). I have the page up and running (i.e. it runs with the appropriate account, it runs PowerShell, etc.) - I want to prompt for and store credentials in a reasonably secure manner. I assume there is some standard way to do this. Or am I reading too much into this as this is a server side application?

Here are excerpts from my code thus far:

  • Default.aspx (these will be changed depending on the scenario):

    <asp:TextBox ID="Input" runat="server" TextMode="MultiLine" Width="400px" Height="73px" ></asp:TextBox>  
    <asp:TextBox ID="InputParam" runat="server" TextMode="MultiLine" Width="200px" Height="20px" ></asp:TextBox>  
    <asp:Button ID="ExecuteCode" runat="server" Text="Execute" Width="200" onclick="ExecuteCode_Click" />
    <asp:TextBox ID="ResultBox" TextMode="MultiLine" Width="700" Height="200" runat="server"></asp:TextBox>
    <asp:TextBox ID="ErrorBox" TextMode="MultiLine" Width="700" Height="200" runat="server"></asp:TextBox>
    
  • Default.aspx.cs:

    protected void ExecuteCode_Click(object sender, EventArgs e)
    {
        // Clean the Result TextBox
        ResultBox.Text = string.Empty;
    
        // Initialize PowerShell engine
        var shell = PowerShell.Create();
    
        // Add the script and an argument to the PowerShell object
        shell.Commands.AddScript(Input.Text);
        shell.Commands.AddArgument(InputParam.Text);
    
        // Execute the script
        var results = shell.Invoke();
    
        // display results, with BaseObject converted to string
        // Note : use | out-string for console-like output
        if (results.Count > 0)
        {
            // We use a string builder ton create our result text
            var builder = new StringBuilder();
    
            foreach (var psObject in results)
            {
                // Convert the Base Object to a string and append it to the string builder.
                // Add \r\n for line breaks
                builder.Append(psObject.BaseObject.ToString() + "\r\n");
            }
    
            // Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
            ResultBox.Text = Server.HtmlEncode(builder.ToString());
        }
    
        //Collect errors
        var PSErrors = shell.Streams.Error.ReadAll();
    
        if (PSErrors != null)
        {
    
            // We use a string builder ton create our error text
            var builder = new StringBuilder();
    
            foreach (var psError in PSErrors)
            {
                // Convert the exception Object to a string and append it to the string builder.
                // Add \r\n for line breaks
                builder.Append(psError.Exception.ToString() + "\r\n");
            }
            // Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
            ErrorBox.Text = Server.HtmlEncode(builder.ToString());
        }
    
    }
    
  • This code won't work from what I understand, but the concept is exactly what I am looking to do.

    PSCredential pscred = this.Host.UI.PromptForCredential("Enter username/password","", "", "");
    shell.Commands.AddArgument(pscred);
    
Community
  • 1
  • 1
Cookie Monster
  • 1,741
  • 1
  • 19
  • 24
  • 1
    It appears some people have interpreted your question has a "recommendation" style question (asking for a library or something like that to solve your problem). I'm not sure that's what you were doing, but I do think you could approach the question in a better way (to make it "on-topic" for Stack Overflow). I think the question would be worthy of reopening if you posted some code with your attempt to collect / store / pass on the info you need, and then describe where you've gotten stuck. – Josh Darnell Dec 06 '13 at 00:36

1 Answers1

2

I think the easiest way is to use impersonation. i.e. you get the credentials of the user, and launch the powershell process as that user which allows you to execute anything you want as that user.

See:

Execute PowerShell cmdlets from ASP.NET With User Impersonation - Has steps to impersonate the current user to run PowerShell

or

How to run PowerShell scripts from ASP.NET with Impersonation - StackOverflow question on how to run PowerShell with impersonation.

Community
  • 1
  • 1
HAL9256
  • 12,384
  • 1
  • 34
  • 46
  • It appears I can't vote up your response given my new account! Anyhow, yes, that is my fallback option. The use cases I am picturing involve a standard user account launching the webpage, picking a function to run (e.g. one that requires administrative privileges) and prompting for administrative credentials, which would be passed in to the script. This would allow a standard account to browse to the website, rather than forcing users to open a browser as their administrator account. – Cookie Monster Dec 05 '13 at 23:55
  • How about checking out this link: http://stackoverflow.com/questions/9909784/impersonating-a-windows-user this way, your regular browsing is under one account, and you can launch the powershell process with another account. – HAL9256 Dec 06 '13 at 00:16
  • Thanks, looks cool! Might end up using that for a few scenarios. If I have an ASP.NET front end though, I'm not sure how to securely obtain and store the credentials for the C# to use. The web side is what I'm least familiar with unfortunately. – Cookie Monster Dec 06 '13 at 00:33