Monday, August 27, 2018

stackoverflow : Top 1%

Finally got there:


There are over 9 million users on stackoverflow and currently I'm sitting at:


Now it gets into the decimals e.g. top 0.5 %

Enjoy!

Friday, August 24, 2018

Misc : My audience

Just out of interest, my audience as reported by Blogger.


Strange that Google has "Unknown Region"?

Chrome is way ahead on the browsers and Windows is way ahead on the OS.

Would have thought the iPad figure would be higher but maybe iPad users have no interest in Identity :-)

Enjoy!

C# : Invalid URI

The full message is:

"Invalid URI : The hostname could not be parsed".

I get this using the URIBuilder class.

Since it was complaining about the hostname I checked the DNS, I checked that I could ping it, I tried the IP address etc. etc.

Eventually worked out that it was because the password contained special characters.

You are apparently supposed to URL encode them.

Just changed the password to use letters and numbers and all was well.

Somewhat misleading error message :-)

Enjoy!

Friday, July 13, 2018

stackoverflow : Answered 1,000 questions

Achievement unlocked!


Most of these are in the Identity space and of course the problem is that in order to answer a question, someone has to ask it first.

It is somewhat of a niche category. I've been on stackoverflow for 9 years and 10 months (at time of writing) so it's taken a while to get here.

Looking at the tags e.g. ADFS:


What's also interesting about this is the other contributors.

Just calling out some of them:

Eugenio Pace and Matias Woloski are the founders of Auth0 and vibronet has recently joined them.

leastprivilege is one of the people behind identityserver.

Across the other tags:


I guess now I need to identify my next achievement!

And onto the next 1,000!

Enjoy!

Thursday, July 12, 2018

Certificates : Displaying errors

Quite often, you can't connect to an SSL site because .NET will tell you that the certificate is invalid.

This openssl command shows you the certificate errors:

openssl s_client -connect company.co.nz:443|openssl x509 -text

The output looks like:

depth=2 CN = Company Root CA
verify error:num=19:self signed certificate in certificate chain
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1f:06:eb:c1:00:34:00:05:56:38
...

etc.

It also checks the intermediate and root CA certificate validation chain.

Enjoy!

Friday, July 06, 2018

Certificates : The remote certificate is invalid according to the validation procedure

I see this error so many times. It is generally on the client side as part of the .NET framework.

The root cause of this is:
  • Your server certificate is self-signed
  • You are using an incorrect host name to connect
  • Your certificate is not trusted
The host name must match the subject name on the certificate e.g. company.com and orders.company.com both point to the same URL but the certificate has been issued to company.com. So that is the name you need to use to get to the web site. Or else you can add the other names to the SAN.

If the certificate is not trusted, you can add it to the "Trusted Root Certification Authorities". But be mindful of security.

I find it useful to log why .NET doesn't like it.

Just in case that article disappears, I've saved the config here.

Key info:

The Network Service account must be able to write to this log so give the account access to the directory. 

Change the log location.

e.g. initializeData="c:\Logs\Trace.log"


Now assume that company.com is not in the DNS and you have an IP address e.g. 124.40.60.80.

Now the URL is 124.40.60.80 but the certificate subject name is company.com. Bingo. You get the error.

The solution is to create a host file entry.

124.40.60.80 company.com

Now you can browse to company.com and the name will match.

Enjoy!

Visual Studio : You need to find somefile.cs to view the source

Debugging through some socket code and suddenly the debugger came up with the above when I tried to step into the .NET code.

It was asking for NetworkStream.cs , Socket.cs etc.

Trying to browse to the file wasn't helping.

So Mr. Google to the rescue.

The solution is:

Visual Studio / Tools / Options / Debugging / General / Enable source server support

Problem solved.

Enjoy!

Tuesday, July 03, 2018

C# : The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly

Busy doing some work with a SQL component.

To check all was well, I set VS to break-point on all CLR exceptions and suddenly it came up with the above error.

WTF?

Lots of discussions with Mr. Google and the usual ton of garbage but then I found this.

Run "cmd" as admin.

cd C:\Windows\Inf\.NET Data Provider for SqlServer

lodctr _dataperfcounters_shared12_neutral.ini

That did the trick.

BTW, lodctr "allows you to register or save performance counter name and registry settings in a file and designate trusted services".

Enjoy!

Monday, July 02, 2018

log4net: Why are all logs written to when I invoke just one?

I was trying to get log4net working and I wanted 3 logs:

  • Console
  • Text file
  • Event log
So the config. looked like:
root
      !--level value="ALL" /
      appender-ref ref="ConsoleLog" /
      appender-ref ref="Log" /
      appender-ref ref="EventLog" /--
 /root
and then e.g.:
appender name="ConsoleLog" type="log4net.Appender.ColoredConsoleAppender"
      mapping
        level value="ERROR" /
        foreColor value="White" /
        backColor value="Red, HighIntensity" /
      /mapping
      layout type="log4net.Layout.PatternLayout"
        conversionPattern value="%date [%thread] %level %logger - %message%newline"/
      /layout
/appender 
and called via e.g. :

private static readonly ILog LogConsole = log4net.LogManager.GetLogger("ConsoleLog"); 

But when I tried e.g.

LogConsole.Info

all three logs were invoked and all three entries were written!

Turns out you need to remove the root level and use e.g.:
logger name="ConsoleLog"
      level value="ALL" /
      appender-ref ref="ConsoleLog" /
/logger
where the  "appender-ref" points to the correct log.

Then all works as expected.

Note: angle brackets removed for display purposes!

Enjoy!

Wednesday, June 20, 2018

Auth0 playground

Auth0 have a neat playground where you can play around with the Lock settings.

Lock is the Auth0 login component.

I was trying to get some extra fields added when the user wants to self-register and we want to capture some extra information.

There are examples but they don't have context i.e. they show you what attribute to set but you don't get to see the full picture.

As usual, the gist is here.


This is the basic screen - notice I've added some of the Asian social providers like Baidu. This isn't part of the js - it's part of the application configuration.


Here is the signup screen. Clicking "United States" shows the drop-down. Also notice the checkbox at the bottom.



Shortening the text shows the error message that is part of the validation.


Enjoy!

Wednesday, May 16, 2018

ADFS : Cookies, tokens and timeouts

This is for Server 2016 (ADFS 4.0).

I've been helping a customer get to the bottom of token timeouts, sessions timeouts etc.

The two best links I've found are:

AD FS Single Sign-On Settings

Active Directory Federation Services (#ADFS) Single Sign On (SSO) and token lifetime settings

and a few lines in:

AD FS Frequently Asked Questions (FAQ)

that are:

"How long are ADFS tokens valid?

Often this question means ‘how long do users get single sign on (SSO) without having to enter new credentials, and how can I as an admin control that?’ This behavior, and the configuration settings that control it, are described in the article here.

The default lifetimes of the various cookies and tokens are listed below (as well as the parameters that govern the lifetimes):

Registered Devices 

PRT and SSO cookies: 90 days maximum, governed by PSSOLifeTimeMins. (Provided device is used at least every 14 days, which is controlled by DeviceUsageWindow)

Refresh token: calculated based on the above to provide consistent behavior

access_token: 1 hour by default, based on the relying party

id_token: same as access token

Un-registered Devices

SSO cookies: 8 hours by default, governed by SSOLifetimeMins. When Keep Me Signed in (KMSI) is enabled, default is 24 hours and configurable via KMSILifetimeMins.

Refresh token: 8 hours by default. 24 hours with KMSI enabled

access_token: 1 hour by default, based on the relying party

id_token: same as access token"

And here we see the first problem - there is a major distinction between registered and unregistered (aka non registered) devices and most of the documentation is for the former.

A registered device is a device that has been provisioned via EMS / Intune. You could add domain-joined here. This allows a user to BYOD and still have access to a company's intranet.

So if you have a customer with a B2C type of scenario where their users have a wide range of devices and never need to access the company intranet, you start to see some problems.

The first issue is that of persistent cookies.

Set-AdfsProperties –EnablePersistentSso

These are not enabled for unregistered devices. You can turn them on with the KMSI (Keep Me Signed In) option.

Set-AdfsProperties -EnableKmsi $true

What you now see in a PC browser is:




 and indeed the cookies are now persistent if you tick the box.

The defaults have changed from 8 hours to 24 as above.

However, on some mobile devices, the onload.js has a:

style="display:none"

which means that it does not display and you are back to square one.

This may be because there is a:

"&prompt=login"

in the query string,

So assuming KMSI is on, you have:

access token = id-token = 1 hour

SSO cookie = refresh token = 24 hours

To change the default:

Set-AdfsProperties – KmsiLifetimeMins int32

and if KMSI is off:

access token = id-token = 1 hour

SSO cookie = refresh token = 8 hours

To change the default:

Set-AdfsProperties –SsoLifetime int32

Also note that there is a KMSI "user component" (which adds the box) and a KMSI "ADFS feature" (that changes the timeout values). 

You don't want the refresh token to time out because that would force the user to re-authenticate.

So you can use the "authorize" endpoint to get a brand new set of tokens. Because the SSO cookie has not yet expired, ADFS will simply mint a new set without any login requirement.

The tokens are "brand new" e.g the id-token will be valid for another hour.

By a "new set", I mean an access token, a refresh token and an id-token.

You get the same behaviour if you call the refresh endpoint.

However, I noticed that although the value of the refresh token is different, it has the same

"refresh_token_expires_in": 72186

value (adjusted by the time it took to do the refresh itself).

So the new refresh token inherits the old "time to timeout".

Enjoy!

Tuesday, April 24, 2018

Stackoverflow : How to treat newbies

Joel Spolsky is writing a series of articles on the evolution of stackoverflow.

Part of this is the treatment of newbies; in particular the arrogant treatment of people who genuinely need an answer but don't know how to ask the question.

Jon Skeet wrote an excellent post on how to ask a question.

The problem arises when they don't know enough to do that.

e.g. "My boss tells me that I need to convert my ASP.NET Membership application to SAML 2.0. I've googled SAML for a whole day and am hopelessly confused".

Now, the standard response on stackoverflow is to close this - too broad - not focused - not a programming question.

All of which is true and this question could also go on serverfault.

But that doesn't help the newbie.

My approach is to say something like:

"OK - you need a SAML stack on the client side. Here's a list of SAML clients, Find one that fits your requirements (language, cost etc.) and read the documentation and samples".

Then I ask what IDP they plan to use?

And depending on that, I may have some more suggestions or links to a good post.

The outcome is that the newbie has something concrete to go on.

(I leave the admin. to other people).

In fact, that's how this blog originally started.

I was answering the same question again and again and so I answered the question in the blog and then posted the link. Major time saving.

The other point is that I can't do their job for them. All I can do is point them in the right direction.

The comments section in stackoverflow is for further questions.

Enjoy!