I ended up using the UI Automation framework, which allowed me to grab a reference to the credential prompt and then fill it out and complete it that way.
Code snippet:
AutomationElement desktop = AutomationElement.RootElement;
//get all windows on the desktop
AutomationElementCollection windows = desktop.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
foreach (AutomationElement window in windows)
{
if (window.Current.ClassName.Equals("#32770")) //security dialog
{
// access the appropriate AutomationElements to enter credentials here
}
}
To interact with an element, you grab the appropriate Pattern object and call its methods (eg Textboxes have a ValuePattern which has a .SetValue() method.
I also used UISpy to find all the values for things like ClassNames, AutomationIds, etc to help find the correct item through .FindAll() and PropertyConditions objects.