IdentityModel.OidcClient library doesn't seem to work with UWP - .net-core

We are using ASP.NET Identity with IdentityServer4. We've added a Client to use with Azure AD. This works great within a web page, that part is working.
Our end goal is a UWP app, so we found the IdentityModel.OidcClient which has a UWP sample. This sample has two browser classes. We configured HTTPS, but the WabBrowser class now refuses to connect to the site at all. If I change the config to hit https://demo.identityserver.io then it works, but all the other config is the same, so I'm not sure what the problem could be. It shows an error message in the pop up browser that it could not connect.
I looked at the SystemBrowser class, but this logs in fine, then the browser window does not close, and even if we close it, the code doesn't move on to get back a result. Looking at the source, this is not surprising, it calls:
Launcher.LaunchUriAsync(new Uri(options.StartUrl));
and that's all. The RedirectUri is not passed in, and mechanism appears to exist to use it. So, the behaviour we see appears to be the extent of what the class can do.
Looking at the console .NET Core sample, it has a SystemBrowser class that works. I updated the UWP sample to use the Fall Creators Update and was able to bring in the ASP.NET Core dlls needed to compile this code. It sets up a class like this:
public LoopbackHttpListener(int port, string path = null)
{
path = path ?? String.Empty;
if (path.StartsWith("/")) path = path.Substring(1);
_url = $"http://127.0.0.1:{port}/{path}";
_host = new WebHostBuilder()
.UseKestrel()
.UseUrls(_url)
.Configure(Configure)
.Build();
_host.Start();
}
and I can confirm this gets called only once, but even if I hard code an unused IP address, I get an error that the IP is in use.
So, at this stage, the sample that exists for UWP works for the demo server but not for ours (I suspect an HTTPS issue, but that's not the error I get), and importing code that works for a Core sample, does not work either. I've spent a couple of days on this and would appreciate a nudge in the right direction.
So, to recap, the WabBrowser seems the best bet but, for my localhost IdentityServer I get this:
and if I try to use a .NET Core library that works elsewhere, it thinks a port is in use. I suspect I need to work out why WabBrowser can't connect to my local site. I have turned off Fiddler. I can browse to my https URL and get a disco document, in the browser, at https://localhost:44305/.well-known/openid-configuration.

There are extra steps necessary to enable localhost in the Web Authentication Broker -
https://msdn.microsoft.com/en-us/library/windows/desktop/jj658959%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

This website gave me the fix. Here is a synopsis:
Remove loopback isolation
For security and reliability reasons, UWP applications are not allowed to send requests to the loopback interface. While Visual Studio automatically creates exemptions for debugged apps, this feature won't be helpful in this case, as the authentication broker always executes in a separate process.
If you see this (cryptic) error message in your Windows event logs, then you're likely facing this issue:
AuthHost encountered a navigation error at URL: [...] with StatusCode: 0x800C0005.
One option to fix it is to use the loopack exemption utility developed by Eric Lawrence. It's natively included in Fiddler 4 but can also be downloaded as a standalone software. To allow the authentication broker to communicate with the loopback interface, exempt the applications starting with microsoft.windows.authhost and save your changes:
If everything was properly configured, you should now see the login/consent page returned by your server.

Related

TodoList sample Bing Maps service returns error with status blank

I am working thru the sample todolist application for the Cordova SDK.
the url is here
https://msdn.microsoft.com/en-us/library/dn832630.aspx
I set up a key on the BING Maps website. I can access the location service sending latitude and longitude thru a standard web browser, pasting in the URL with my key.
However the angular call always fails. What is worse is the error is always blank. no status code no error message. Was thinking it must be CORS.
I have run through the sample and downloaded the code sample and both have the same issue.
For anyone going thru the sample. I have realised today that Angular is evil. They say it is nicely testable javascript with dependancy injection, however it doesn't seem to be too interested in telling you what the error is when you have one, it just fails. Great and noble programming ideas, but without an error message it isn't much good.
Anyhow the fix is that Angular is very strict about json code so the line in services.js for the Bings Maps Service method getAddressFromPosition
it used to work with .get() but this was probably an old version of Angular when the demo was written. I tried using 1.2 but the Ripple emulator didn't like references to browser specific code. So I used the latest 1.3.13 I believe.
This is where to access the Bing location service with the Cordova geolocation coordinates returns Json, but Angular wants them wrapped in JSONP. searching the increasing fragmented web it appeared the error might be CORS no, so a many different people had their JSONP calls in controllers, modules, services, some using $http others $resources. Finally using bits and pieces I got JSONP to work with $resources and to plug it into the $promise the call from the controller requires. I used a static Url with Coordinates I knew worked, so you will have to use the :param angular notation to put those back in. Hope it helps someone.
So change to:
getAddressFromPosition: function (position) {
var resource = $resource(url, {}, {
jsonp_query: {
method: 'JSONP'
}
});
return resource.jsonp_query().$promise.then(function (response) {
return response.resourceSets[0].resources[0].address.formattedAddress;
}, function (error) {
return position.coords.latitude + "," + position.coords.longitude
});
edit:
I put the above in and it worked. However the problem was for some reason, perhaps thru debugging, another instance of the app was deployed on another port in ripple. This then change the app to run on this new port. The initial port was 4400. The problem is that and $http or $resource calls in angular have to go thru this emulator, and the emulator was seeing this as cross domain, unless it is configured to the same port the app is running under.
so Url:
http://localhost:4409/index.html?enableripple=cordova-3.0.0-iPhone5
then in the Settings Div dropdown on the right side, the Proxy Port must also be set to 4409 or else the browser will complain that the $http request is cross-domain, before the emulator actually executes it to query Azure mobile service or Bing maps.
So this was very frustrating. However VS Cordova has definately reduced the amount of bits you have to configure to make hybrid mobile apps, there are still little glitches like this which can trip you up. I assumed it was something with angular, because there was no error messages, but in Chrome in the Dev Tools console that was where the error was, and after some googling it was plain that it was the ripple emulator running on a different port than its proxy was not allowing the call to be forwarded on due to Access-Control-Allow not being set.

Why won't OAuth work on web server?

I have an ASP.Net web application running on Windows Server 2012, and need to make calls to social networking sites using oauth to generate some of the page content. Everything works on my development machine, but I can't even get a single response back ("unable to connect to the remote server" error).
I disabled the firewall to test that. No luck. I created a console application to test it that way. A simple HttpWebRequest will get the html for any page I throw at it, but not any oauth request. I've used different libraries to try to achieve this, including Linq2Twitter, Spring.Social, and HigLabo. All work locally, but not on the server. I've found nothing useful in the server event log.
Can anyone give me some clues what might be happening?
EDIT: Here's some code I'm using with the HigLabo library to try to retrieve the user timeline.
using HigLabo.Net.Twitter;
var cl = new TwitterClient(consumerKey, consumerSecret, accessToken, accessTokenSecret);
var rr = cl.GetHomeTimeline();
foreach (var r in rr)
{
//Console.WriteLine(r.CreatedAt + ":" + r.Text);
}
I'm aware that accessToken & accessTokenSecret aren't/shouldn't be necessary for a simple timeline read, but this is just to make sure it works first.
This turned out to be a firewall issue, as had been suspected. But not the server firewall. This was a problem with the ISP. They had an internal firewall that was blocking all traffic to/from the social network sites. They were able to resolve it quickly with a phonecall, but it was not a coding or configuration error on my part.

ASP.NET - Help Testing & Debugging PKI Authentication

I am working on an ASP.NET WebForms application, and I have been asked to switch from Windows Form Authentication to PKI Certificate Authentication; something I know very little about.
After reviewing various web posts and their code snippets, I thought I knew enough to at least begin sniffing a PKI Certificate (or any client certificate for that matter). Specifically I am using:
X509Certificate2 cert = new X509Certificate2(Page.Request.ClientCertificate.Certificate);
X500DistinguishedName dn = cert.SubjectName;
So I put a breakpoint on the 2nd line, hit F5 from Visual Studio. Debugging starts, but 'cert' is always null. I then realize that I have no Personal certs on my computer, so I download the Firefox add-on Key-Manager, create a dummy certificate, and try again with the same result, 'cert' is always null.
So then, I start screwing around with the command-line tool makecert, but still 'cert' is always null.
I am using IIS Express 7.5 for debugging purposes, tried both http and https.
What do I need to do to attach the personal cert to any web requests, and have them get picked up by my ASP.NET application?
Do you have IIS express setup to require client certs?
Please look here for a similar question/answer:
https://serverfault.com/questions/309690/how-to-configure-iis-express-to-ask-for-client-certificate
http://www.iis.net/ConfigReference/system.webServer/security/authentication/iisClientCertificateMappingAuthentication

BizTalk SOAP port password in binding file

I've inherited a BizTalk 2006 application that uses several SOAP ports to request data from a 3rd party web service. The web service is secured by "basic" authentication - username / password. After making a few enhancements to the application I deployed to an integration test server which has access to the 3rd party web service. The BizTalk app was unable to retrieve the data and I soon realised that I had forgotten to set the username / password on the SOAP send ports. I wanted the make deployment of the BizTalk app as automated as possible because I may not be present when it is deployed to the live server. I opened up the binding file, located the 1st of the problem SOAP send ports and looked for the * that BizTalk uses to replace the password - except that it doesn't! It seems that the password for SOAP ports is set to NULL rather than *, see here for more details:
http://msdn.microsoft.com/en-us/library/aa547319.aspx
I proceeded to update the binding but when I came to test, after importing my amended binding file, I found that I had the same problem as before. I've double checked and can confirm that the correct password is now present in the binding file but, although BizTalk doesn't complain during the import, when I run the app I get the following exception:
Details:"ArgumentNullException: String reference not set to an instance of a String.
Parameter name: s
".
If I then manually amend the password through the BizTalk admin console everything work fine.
Has anyone else had a similar problem with the bindings for a SOAP port - does anyone have a solution?
I've been bit by something like this in the past. The password is either put in as '****'. This is ok. I wouldn't want all of my secrets exported with the binding file. What does get you is when you export the bindings and you leave the password NULL. The Variable Type (vt) attribute on the XML element for the password is set to vt="1" which is the same as NULL. It won't matter what you put in for the password. It may even cause the error you described. I would suggest you include a copy of the binding XML for review.
I've never seen this problem before - I'm doing exactly what you are trying to do and it works perfectly.
I've included the <TransportTypeData> element from one of my BizTalk bindings that works. Hopefully having something to compare against helps.
<TransportTypeData>
<CustomProps>
<AuthenticationScheme vt="8">Basic</AuthenticationScheme>
<AssemblyName vt="8">WebService.ProxyClass, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=xyz</AssemblyName>
<Username vt="8">soapUser</Username>
<UseProxy vt="11">0</UseProxy>
<UseSoap12 vt="11">0</UseSoap12><UsingOrchestration vt="11">0</UsingOrchestration>
<UseSSO vt="11">0</UseSSO>
<Password vt="8">MYPASSWORD</Password>
<ProxyPort vt="3">80</ProxyPort><AssemblyPath
vt="8">C:\ProxyClass\bin\Debug\ProxyClass.dll</AssemblyPath>
<TypeName vt="8">ProxyClass.Webservice.servicesService</TypeName>
<MethodName vt="8">PickupRequest</MethodName>
<UseHandlerSetting vt="11">-1</UseHandlerSetting>
</CustomProps>
</TransportTypeData>

Webservice.wsdl and credentials

So I've got a bit of an issue I'm trying to work through. Perhaps some Flex guru could assist?
I have a WebService instance that attempts to load a WSDL file from our JBoss Application Server. If I do something like this:
webService = new WebService();
webService.destination = WebService.DEFAULT_DESTINATION_HTTP;
webService.wsdl = "http://<removed>/services/ApiService?wsdl";
webService.loadWSDL();
everything works fine. The WSDL is loaded successfully and the application can invoke methods against the web service.
The issue is when I need to add some HTTP authentication to the mix:
webService.setCredentials(userName, password);
this line ends up throwing an error stating that credentials are only supported on HTTPS. Ok fair enough, I want to use secure HTTPS anyway!
So then I tried to change it up to this...
webService = new WebService();
webService.destination = WebService.DEFAULT_DESTINATION_HTTPS;
webService.wsdl = "https://<removed>/services/ApiService?wsdl";
webService.setCredentials(userName, password);
webService.loadWSDL();
and now the WebService instance cannot load the WSDL. The error received is:
[FaultEvent fault=[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Unable to load WSDL. If currently online, please verify the URI and/or format of the WSDL (https://<removed>/services/ApiService?wsdl)"] messageId="6905CC5B-5317-C4B3-2D12-84647EE648A7" type="fault" bubbles=false cancelable=true eventPhase=2]
I can reach this URI in the browser just fine and it returns the WSDL as expected.
I am not a Flex guy (learning) but instead a Java developer. I am trying out Flex as a potential client to our system but this has caused me all kinds of grief today. Google doesn't appear to have any quick answers for me and I am a bit stumped.
First question on StackOverflow so hopefully this gets a bite somewhere and helps some other poor Java dev staying late in the office on a Friday night :-)
This seems to be related to your question. We are planning to use https in the future, so I'm curious to know the solution of your problem.

Resources