Programmatically login to site with Apache basic authentication from WPF .net application - wpf

We have a requirement to open a web site URL in default browser of the client machine from our WPF application. All this time we were using simple Process.Start(URL) and it was working fine. Until now where one of customer has this "URL" behind basic authentication. The site they want us to browse using URL is hosted on Apache web server. From what I know, if we have https://username:password#domain.com it directly takes us in site without the username/password challenge and it works fine in Chrome and Firefox, however newer version on IE stopped supporting it for security reasons.
Can someone suggest some alternate approach to achieve same considering following objectives ?
List item
Browse to URL with passing in username password.
Open default browser in client's desktop machine.
Don't want to user browser control
At minimum should work in 3 browsers - IE, Firefox and Chrome
We cannot make changes to client desktop's machine, so solution shouldn't require any special settings.

The workaround for developers from the Microsoft Support site : http://support.microsoft.com/kb/834489
Workarounds for application and Web site developers
URLs that are opened by objects that call WinInet or Urlmon functions
For objects that use an HTTP or an HTTPS URL that includes user
information when they call a WinInet or Urlmon function such as
InternetOpenURL, rewrite the object to use one of the following
methods to send user information to the Web site: Use the
InternetSetOption function and include the following option flags:
INTERNET_OPTION_USERNAME INTERNET_OPTION_PASSWORD Note For these
flags, the InternetSetOption option must have a handle returned by the
InternetConnect function. Therefore, if the application uses the
InternetOpenUrl function, modify the application to use the
InternetConnect, HttpOpenRequest and HttpSendRequest WinInet
functions. For more information about how to use these functions,
visit the following Microsoft Web sites:
http://msdn2.microsoft.com/en-us/library/Aa384363
http://msdn2.microsoft.com/en-us/library/Aa384233
http://msdn2.microsoft.com/en-us/library/aa384247.aspx Use the
IAuthenticate Interface. For more information about how to use the
IAuthenticate Interface, visit the following Microsoft Web site:
http://msdn2.microsoft.com/en-us/library/ms775080.aspx
Was this option tried ?

Related

Best practice for OAuth/OIDC SSO with a WinForms app?

We are adding modern authentication (OAuth/OIDC) to an application that currently uses Windows integrated authentation for single sign on. The user signs into Windows workstation and those credentials can be used by many applications with authentication happening transparently over Kerberos.
Our app is a dot net web services based application and we have a client for users with browsers and a desktop client in WinForms. The browser scenario is no issue as the identity provider stores information in the browser that can be reused across applications in a similar way to WIA (IWA), but we are unsure the best way to handle the WinForms desktop application case. Currently the WinForms application opens a browser window to authenticate using the typical browser based method. The details from the identity provider are passed through the browser back to the WinForms app using a redirect and a custom protocol based URL.
This all works fine, but the user experience is not super tight and, for the case where the user is already logged in, requires them to press a button in the browser window as current Chromium based browsers seem unwilling to do a redirect without a recent user interaction.
Is there a better way?
The standard options according to RFC8252 are as you describe:
Log in via the system browser
Use either a loopback or private scheme based URL
I have a few blog posts about this and it is a tricky flow. The posts link to code examples you can run that explore the UX a little. You may find that a loopback URL avoids the need for a button click, though personally I think private scheme based URLs are cleaner.
There are UX things you can do, such as an interstitial web page to better control what happens in the disconnected browser. I have seen companies redirect to their own website after desktop logins, to make the UX better.
In the longer term I expect this to be replaced with API Driven OAuth Flows so that you never need to leave the app. For now you may have to live with some UX linitations, but it is the right flow from a security viewpoint.

CefSharp Browser control not working with Azure AD Conditional access

We configured our Azure AD application registration to use “Conditional Access” restrictions to lock down the application to machines that are registered to the domain. Unfortunately, in order to successfully authenticate with Conditional Access enabled on chromium based browsers, a browser extension is required
There is quite a bit of documentation around this on Microsoft’s website
• Conditional Access require managed device - Azure Active Directory | Microsoft Docs
• Conditions in Conditional Access policy - Azure Active Directory | Microsoft Docs
when the user trying to log in with cefsharp browser control we see the following error. Tried enabling the browser extension did not help
Sadly CefSharp will not work with Device Management policy.
To prove device identity on Windows, the Windows broker (WAM) needs to intercept the network traffic and inject the device id. The following browsers are supported: Edge, old IE, Chrome with Windows Accounts extension and I'm not sure about Firefox.
Since CefSharp is based on Chromium but does not have the extension (and, afaik, there is no way to install it), WAM cannot inject the device ID in the requests made to AAD.
Possible workaround:
use WebView2 SDK on Windows, which is based on Edge, which is also based on Chromium... At the time of writing, Mac support is planned but not released.
And use Cef on Mac and Linux.
Due to the nature of this issue and complexity behind it, I had to migrate off CefSharp to use the new WebView2 browser component until there is a supported approach released for CefSharp and other third-party browsers to inject logic like the code below. The EdgeWebView2 works by enabling the SSO flag get_AllowSingleSignOnUsingOSPrimaryAccount
C# .NET example code below using the EdgeWebView2 browser component (as of writing this is the only way I know to defeat the authentication message "You can't get there from here"):
CoreWebView2EnvironmentOptions envOptions = new CoreWebView2EnvironmentOptions()
{
AllowSingleSignOnUsingOSPrimaryAccount = true
};
CoreWebView2Environment env = CoreWebView2Environment.CreateAsync(options: envOptions).Result;
webview.EnsureCoreWebView2Async(env);
webview.Source = new Uri("https://portal.azure.com/");

Google Analytics with Silverlight HTTPS cross domain policy problems

I'm sending simple messages to Google Analytics from a Silverlight app. They look something like this (data changed):
http://www.google-analytics.com/collect?v=1&tid=foobar&cid=foobar&t=pageview&dp=foobar&dt=foobar
Very simple API. If I use HTTP it works beautifully.
If I use HTTPS, I run afoul of Silverlight's cross domain policies. According to the docs, google-analytics.com needs to approve the cross-domain call by hosting either a clientaccesspolicy.xml (Silverlight-specific) or crossdomain.xml (original used by FLASH). Turns out they do host crossdomain.xml, and I can see that Silverlight downloads it (via Fiddler), but apparently Silverlight doesn't like the file's content and doesn't allow HTTPS calls to that domain (System.Security.SecurityException).
So.. at least at the moment, I can't use Google Analytics from Silverlight using HTTPS. Does anyone know a work around for this issue?
Note, I can't just use HTTP, because that causes IE to issue a "Allow Mixed Content" prompt which causes problems for some of our customers. I need to use HTTPS like the rest of our app.
EDIT: OK, I took a totally different approach, using HtmlPage.Window.Invoke to call a 3 line Javascript function to do the asynchronous send rather than using WebClient in the Silverlight code. Works like a champ. Anybody see any potential problems with that?
I suspect there may be a way to make this work, because I know google-analytics.com is very cross-domain friendly for exactly this reason.
If you absolutely can't get it to work another option would be to proxy the hits. If you do this, you'll want to make sure to use the ua and uip override fields in the hit you're sending so that they show up in Google Analytics with the IP address and User Agent of the original visitor and not your server.
Here's some more info on using a proxy server with the Measurement Protocol:
https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#using-a-proxy-server

Using the Google Users Service with jQuery Mobile

I was wondering what would be a better way to let my jQuery Mobile app "know" the user of the app after completing a registration process.Since the handlers in my Python Google App Engine app expect a username, i decided to store the username in localstorage and then use this as part of any request made to the server.But i don't think this is a good design idea (?).After a lot of search, i have found that jQuery Mobile does not support Google login (Please correct me if am wrong) So i have decided to use the Users Service from the server end.I am confused on how to implement this, since the users service from Google has it's own sign-in form.
Is it possible to use this same service with jQuery? If so, can i change the design of the sign-in form to blend in with the design of my jQuery app?
jQuery Mobile is just a template designer created directly for mobile web applications using a mobile web browser. It does not possess any connections with server side scripting automatically.
You need to create a connection using server side scripting.
Once you login in using the Google Login, your app associates it with the Google account.
jQuery is just a browser scripting. It does not have an automatic connection with the server unless you connect using AJAX to request to a server, but still need to code the server using HTTP protocol (as a tunnel) and server side scripting language like Java, Python, or PHP.
If you just want to get the "username" using a javascript, you may use REST to get the user information after login. You may look for how JSON or XML REST is created (but putting the username on local storage is not a bad option, without the password, however it may get deleted if you clear the root), but knowing that you are already connected with Google Sign in, just as long as you are already logged in with Google, your app should be able to retrieve the Google username.
Udacity also contains a complete course about web development focused on Google App Engine using Python, and how you may use cookies, password encryption, as well as user login. A detailed information about HTTP protocol is also discussed.
https://www.udacity.com/course/cs253
Note that the course I took existed 2 years ago. It may be different now.

Silverlight Client UserName

I am trying to return the Client UserName back into Silverlight by using HttpContext.Current.User.Identity.Name in the .aspx page that starts the application.
I have this hooked up to InitParams working fine passing it into silverlight with the ASP.Net Development Server but when I change to an IIS Web site it returns an empty string.
All of our users will be on the same IP subnet with different domains. This is a intranet app. I need to know who they are, preferably without authenticating, in order to load the proper interface. I do not have any Windows or Forms authentication established in the app yet.
....is it possible?
Without authentication on the server-side, I believe this is not possible. You'll have to have the ASP.NET page authenticate in order for it to write the client's username into that init param.
The test web server's process is running as the local developer, it probably appears to be working since both the client and server are running as the same user.
Suggestion:
Enable Windows authentication in IIS for that application folder that hoses the ASP.Net page. Disable anonymous. This should (in theory) be fine for the intranet. At this point I think you should be able to get Authenticated user from HTTP context. We use Thread.CurrentPrincipal.Identity.Name since we're doing this in a WCF web service.
Not all browsers support Windows authentication. IE and Chrome seem to work the best. Firefox requires you to enable this per-site (look up the "trusted-uris" settings, note that Negotiate and NTLM are separate settings). Safari and Opera as well as non-windows clients, I'm not sure any more.
To get more consistent support across browsers look into the "alternative" client HTTP in Silverlight. However, I guess this wouldn't work with setting init params in the asp page. If you could make an additional request to another ASP page (or a web service) to get the user after loading you could choose to use this other http stack. I found it supports authentication itself, regardless of the browser.

Resources