tag:blogger.com,1999:blog-111953592024-03-06T09:32:43.586+13:00Random thoughts and collisionsIdeas and thoughts about Microsoft Identity, C# development, cabbages and kings and random flotsam on the incoming tidenzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.comBlogger675125tag:blogger.com,1999:blog-11195359.post-46753305121889575702020-09-22T20:27:00.002+12:002020-09-22T20:27:42.708+12:00Misc: New blog<p> I've been doing this for a while and the reason for "hiding" behind "nzpcmad" longer exists.</p><p>So jump over here for my <a href="https://medium.com/the-new-control-plane">new blog</a>!</p><p>Thanks for all the comments and input over the years!</p><p></p><p> I will still monitor the blog for comments etc.</p><p>Enjoy!</p><p><br /></p>nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-26544614684383224062020-03-31T13:58:00.002+13:002020-03-31T13:58:32.094+13:00Misc : One million hitsI don't blog much here anymore but just hit a milestone:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSYM3nd2nX7IbqQcRT1XHnNKO5N_GJTW6MCopV3i8497IyNNP-QBXpecx3yAsDfA48kpnRhD3C7757OWPPCXXs9v9po0l7P-VOto5dz6jskaxxa8ZxaUC-yUuaJdB_MyP004rB/s1600/Blogger.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="144" data-original-width="1284" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSYM3nd2nX7IbqQcRT1XHnNKO5N_GJTW6MCopV3i8497IyNNP-QBXpecx3yAsDfA48kpnRhD3C7757OWPPCXXs9v9po0l7P-VOto5dz6jskaxxa8ZxaUC-yUuaJdB_MyP004rB/s640/Blogger.PNG" width="640" /></a></div>
<br />
Over a million hits!!!<br />
<br />
Somewhat humbled to think I've helped a large percentage of those. <br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-43886685232857037122019-03-08T09:39:00.002+13:002019-03-08T09:39:24.870+13:00AD : Domain Controller password policyEvery now and then you get an error:<br />
<br />
"<span for="newPasswordInput" id="errorText">Unable to update the
password. The value provided for the new password does not meet the
length, complexity, or history requirements of the domain.</span>"<br />
<br />
So you need to find out the allowed length in the password policy.<br />
<br />
An easy way to do this is to run:<br />
<br />
<i>secpol.msc</i><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvUGBOOpvqn22HetolGZy9XOzpaWKhe32WR9zrXjQB3D3raZ1CGvdhxUB8xQFB-R5EAjr99W5jvU4ksqlybCbvNE52hacvjTMg_xMKkcGGELHb7eK-o6v7wyc6lCctMCAio2u3/s1600/secpol.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="150" data-original-width="766" height="75" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvUGBOOpvqn22HetolGZy9XOzpaWKhe32WR9zrXjQB3D3raZ1CGvdhxUB8xQFB-R5EAjr99W5jvU4ksqlybCbvNE52hacvjTMg_xMKkcGGELHb7eK-o6v7wyc6lCctMCAio2u3/s400/secpol.PNG" width="400" /></a></div>
<br />
Other reasons for this message are that you have already changed your password in the last 24 hours or that you have reused a password that you used in the last 24 passwords.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-30037854669486272872019-02-27T15:27:00.000+13:002019-02-27T15:27:04.561+13:00IdentityServer: IResourceOwnerPasswordValidatorI was looking at idsrv4 and how to integrate it with a custom user store. In this case it was SQL Server.<br />
<br />idsrv4 uses .NET Core 2.2 but a lot of the samples I found were for earlier versions of .Net Core.<br /><br />Some of the samples used IUserService but I couldn't find that.<br /><br />So Mr Google to the rescue.<br /><br />e.g.<br /><br /><a href="https://stackoverflow.com/questions/35304038/identityserver4-register-userservice-and-get-users-from-database-in-asp-net-core">https://stackoverflow.com/questions/35304038/identityserver4-register-userservice-and-get-users-from-database-in-asp-net-core</a><br /><br />"In IdentityServer4. IUserService is not available anymore, now you have to use IResourceOwnerPasswordValidator to do the authentication and to use IProfileService to get the claims."<br /><br />The problem I have with this is that Resource Owner Password is not just a random method name. It's the name of an OAuth flow! Most people don't realise this.<br />
<br />
My client used implicit flow. Using IResourceOwnerPasswordValidator makes no sense.<br />
<br />
So you can just use a controller to authenticate the user like the AccountController.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-6379682136982214262019-01-29T13:52:00.001+13:002019-01-29T13:53:12.477+13:00Azure : Web API - The requested resource does not support http method 'GET'I was running a web API on Azure and doing a POST.<br />
<br />
The full error is:<br />
<br />
{<br />
"Message": "The requested resource does not support http method 'GET'."<br />
}<br />
<br />
That's weird because the method is decorated with [HttpPost] and I was doing a POST.<br />
<br />
Then I noticed that I was calling Azure with a http connection.<br />
<br />
Changing to https fixed the issue.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-50756222040749156922018-12-06T09:34:00.002+13:002018-12-06T09:34:21.836+13:00ADFS : MSIS7042 - The same client browser session has made '6' requestsThe full error message is:<br />
<br />
<i>Exception details:
Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The
same client browser session has made '6' requests in the last '7'
seconds. Contact your administrator for details.</i><br />
<br />
There are many causes for this; one being the "missing /" on the identifier.<br />
<br />
I found one recently where I was running an ASP.NET MVC application inside VS that was authenticated via ADFS. This used the OWIN WS-Fed middleware.<br />
<br />
I couldn't authenticate because of this error.<br />
<br />
ADFS will only accept https connections so the RP was configured with a:<br />
<br />
<i>https://localhost/...</i><br />
<br />
endpoint<br />
<br />
But on VS, inside "Properties / Web", I noticed that the URL was:<br />
<br />
<i>http://localhost/...</i><br />
<br />
Setting this to https fixed the problem.<br />
<i><br /></i>
Go figure.<br />
<br />
I found a similar solution <a href="https://stackoverflow.com/a/38203126/9922">here</a>. <br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-81426769369016878902018-11-23T08:04:00.005+13:002018-11-23T11:10:53.401+13:00Azure AD : Getting the UPNI've been playing around with the custom SAML connection in Azure AD and the "claims transformations" that you can do e.g. tolower.<br />
<br />
My interest was Guest accounts.<br />
<br />
The user screens don't show the UPN so I needed to do this with PowerShell.<br />
<br />
<i>connect-azuread -tenant tenantname</i><br />
<i><br /></i>
<i>Get-AzureADUser -Filter "userType eq 'Guest'" -All $true | select Displa<br />yName,UserPrincipalName,Mail,Department,UserType,CreationType,RefreshTokensValid<br />FromDateTime,AccountEnabled</i><br />
<br />
This displays:<br />
<br />
DisplayName : Joe<br />
UserPrincipalName : joe@company.com#EXT#@tenantname<br />
Mail : joe@company.com<br />
Department :<br />
UserType : Guest<br />
CreationType : Invitation<br />
RefreshTokensValidFromDateTime : 21/11/2018 11:13:58 p.m.<br />
AccountEnabled : True<br />
<br />
Or if you wanted the top 10:<br />
<br />
<i>Get-AzureADUser -Filter "userType eq 'Guest'"<b> -Top 10</b> | select DisplayNa<br />me,UserPrincipalName,Mail,Department,UserType,CreationType,RefreshTokensValidFro<br />mDateTime,AccountEnabled</i><br />
<br />
Or complex filter:<br />
<br />
<i>Get-AzureADUser -Filter "mail eq 'joe@company.com' <b>and</b> userType eq '<br />Guest'"</i><br />
<br />
If you want to see the full list of Azure AD attributes with the complete schema, use:<br />
<br />
<i>Get-AzureADUser -All $true | fl > allad.txt </i><br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-22303394193048306572018-10-24T08:38:00.002+13:002018-10-24T08:39:20.127+13:00Azure B2C : Calling a web API from Azure AD B2C using data typesThere is a good overview <a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-custom-rest-api-netfw">here</a>.<br />
<br />
In terms of the data types that you can pass, these can be: <br />
<ul>
<li>boolean</li>
<li>date</li>
<li>dateTime</li>
<li>int</li>
<li>long</li>
<li>string</li>
<li>stringCollection</li>
<li>alternativeSecurityIdCollection</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhiV8hIhknZBeIKG4Zw2yiQ0Ftf-UKsG2mZsCB6u8pOC8BbVUIWvPMlhoZ8u4fETPBqWjNMsMhQ6p858bVDKAcRG1n-y9htxbq6Hee7y2rE-tuA39AK4IAZbiv0KvCJcyiNcA/s1600/Screen+Shot+10-24-18+at+08.30+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="485" data-original-width="600" height="321" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhiV8hIhknZBeIKG4Zw2yiQ0Ftf-UKsG2mZsCB6u8pOC8BbVUIWvPMlhoZ8u4fETPBqWjNMsMhQ6p858bVDKAcRG1n-y9htxbq6Hee7y2rE-tuA39AK4IAZbiv0KvCJcyiNcA/s400/Screen+Shot+10-24-18+at+08.30+AM.PNG" width="400" /></a></div>
<br />
The above is the XML to define some of the claim types.<br />
<br />
In terms of the JWT returned, the claims look like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDB5S-cF-a0uF5viWw3Y-yXG-d4yc45FpFckupg7J6d4l5c-q-9bdrD0eQgRSCqysecDV3yb4by6xz2TxTZPlkOmzL30WjRnYjP_n5yoNu1fOxyM8kLgNs26cwlk1wcsqORLyy/s1600/Screen+Shot+10-24-18+at+08.36+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="585" data-original-width="600" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDB5S-cF-a0uF5viWw3Y-yXG-d4yc45FpFckupg7J6d4l5c-q-9bdrD0eQgRSCqysecDV3yb4by6xz2TxTZPlkOmzL30WjRnYjP_n5yoNu1fOxyM8kLgNs26cwlk1wcsqORLyy/s400/Screen+Shot+10-24-18+at+08.36+AM.PNG" width="400" /></a></div>
<br />
Enjoy!nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-67551110902046718862018-09-11T08:09:00.002+12:002018-09-11T08:09:55.609+12:00Misc - a busy day at the office!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkORmkG6M5S7JuF-ICDUQxmnp6uLsLiOoOJ7jlN0VgvTEbCjECehsqj8U6N7oSgfuwUOZG3f5wNl_EzB430lUEXcfXKeis-eTaGe63fCimRYoeZouBrHpvjvQHLb0a9RBOpB_7/s1600/Screen+Shot+09-11-18+at+08.07+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="637" data-original-width="800" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkORmkG6M5S7JuF-ICDUQxmnp6uLsLiOoOJ7jlN0VgvTEbCjECehsqj8U6N7oSgfuwUOZG3f5wNl_EzB430lUEXcfXKeis-eTaGe63fCimRYoeZouBrHpvjvQHLb0a9RBOpB_7/s400/Screen+Shot+09-11-18+at+08.07+AM.PNG" width="400" /></a></div>
<br />
Busy on the forums!<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-69051415507697825482018-08-27T08:12:00.001+12:002018-08-27T08:12:53.611+12:00stackoverflow : Top 1%Finally got there:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWHOso7ooyvlUVoNmz9JDfsPYC_5AsxtqaVv4xB2lFKeu5_VjaKulrTSDOfb0yq6E8my3WKq83tKWnYfa6sgvR4_ia0GAPIp-LetRVApBXBIXNQTaXxFnX4yiWmEqzu1uMBaRn/s1600/Screen+Shot+08-27-18+at+08.07+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="210" data-original-width="440" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWHOso7ooyvlUVoNmz9JDfsPYC_5AsxtqaVv4xB2lFKeu5_VjaKulrTSDOfb0yq6E8my3WKq83tKWnYfa6sgvR4_ia0GAPIp-LetRVApBXBIXNQTaXxFnX4yiWmEqzu1uMBaRn/s400/Screen+Shot+08-27-18+at+08.07+AM.PNG" width="400" /></a></div>
<br />
There are over 9 million users on stackoverflow and currently I'm sitting at:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm5Nn5d_oEO9XOQmvJP5qtx8L5-fk3VGX9frKAR1FEGjitLH-5NgfWVazpIvYjegSwK_tsFtfawu8CV7npDvi3QJDfZ7qnVn1F9fn6CQSZhEHAielqvRryE0wOVbARUO-S6g8o/s1600/Screen+Shot+08-27-18+at+08.09+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="102" data-original-width="740" height="55" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm5Nn5d_oEO9XOQmvJP5qtx8L5-fk3VGX9frKAR1FEGjitLH-5NgfWVazpIvYjegSwK_tsFtfawu8CV7npDvi3QJDfZ7qnVn1F9fn6CQSZhEHAielqvRryE0wOVbARUO-S6g8o/s400/Screen+Shot+08-27-18+at+08.09+AM.PNG" width="400" /></a></div>
<br />
Now it gets into the decimals e.g. top 0.5 %<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com1tag:blogger.com,1999:blog-11195359.post-32070830579411253622018-08-24T14:04:00.000+12:002018-08-27T07:40:50.648+12:00Misc : My audienceJust out of interest, my audience as reported by Blogger.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiONcZ3jnjqbUNCNzk6h2NuBj5KFdY8Qd15YZ6-AfB1qH5b1NXJf-6s2_4BoAOThTaNv9-gFFeG1_tudJdUlYq7W9R5-2uYAMNnwuFaGS9dDsX5OydH3Ea6I0EHzncC08IL1pLd/s1600/Screen+Shot+08-24-18+at+01.29+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="523" data-original-width="800" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiONcZ3jnjqbUNCNzk6h2NuBj5KFdY8Qd15YZ6-AfB1qH5b1NXJf-6s2_4BoAOThTaNv9-gFFeG1_tudJdUlYq7W9R5-2uYAMNnwuFaGS9dDsX5OydH3Ea6I0EHzncC08IL1pLd/s400/Screen+Shot+08-24-18+at+01.29+PM.PNG" width="400" /></a></div>
<br />
Strange that Google has "Unknown Region"?<br />
<br />
Chrome is way ahead on the browsers and Windows is way ahead on the OS.<br />
<br />
Would have thought the iPad figure would be higher but maybe iPad users have no interest in Identity :-)<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-19434646459294836562018-08-24T13:25:00.000+12:002018-08-24T13:25:40.390+12:00C# : Invalid URIThe full message is:<br />
<br />
"Invalid URI : The hostname could not be parsed".<br />
<br />
I get this using the URIBuilder class.<br />
<br />
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.<br />
<br />
Eventually worked out that it was because the password contained special characters.<br />
<br />
You are apparently supposed to URL encode them.<br />
<br />
Just changed the password to use letters and numbers and all was well.<br />
<br />
Somewhat misleading error message :-)<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-66111006600979380942018-07-13T07:11:00.001+12:002018-07-13T07:12:37.487+12:00stackoverflow : Answered 1,000 questionsAchievement unlocked!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7jiz5rj2gwnlt10flcCStA9YAurNSvpPl5dBLFTUmq99igGwdiPYAShBgtQ9OgY82ltjHzXB1-7dTLGJXhi3TEnvATmRJKmx2E619W8jScQpEOGXJju8WgL74XfcOCTxQehk/s1600/Rep.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="242" data-original-width="972" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh7jiz5rj2gwnlt10flcCStA9YAurNSvpPl5dBLFTUmq99igGwdiPYAShBgtQ9OgY82ltjHzXB1-7dTLGJXhi3TEnvATmRJKmx2E619W8jScQpEOGXJju8WgL74XfcOCTxQehk/s400/Rep.PNG" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
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.<br />
<br />
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.<br />
<br />
Looking at the tags e.g. ADFS:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibh5ynMJvxwfRcTJVvWCOqciX-IlJjoEerTK5gITL-91bxxzBG1GwQWoNPkbPIM0Hmx-rXCbwGVMWdudeeUDyljiz8Ewax3wKC2_LcpbSZUUHFNg5KoXYOLP2TFPyc52VefI6G/s1600/ADFS.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="723" data-original-width="607" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibh5ynMJvxwfRcTJVvWCOqciX-IlJjoEerTK5gITL-91bxxzBG1GwQWoNPkbPIM0Hmx-rXCbwGVMWdudeeUDyljiz8Ewax3wKC2_LcpbSZUUHFNg5KoXYOLP2TFPyc52VefI6G/s640/ADFS.PNG" width="536" /></a></div>
<br />
What's also interesting about this is the other contributors.<br />
<br />
Just calling out some of them:<br />
<br />
Eugenio Pace and Matias Woloski are the founders of Auth0 and vibronet has recently joined them.<br />
<br />
leastprivilege is one of the people behind identityserver.<br />
<br />
Across the other tags:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilF8QDJL_ha9QAKav1M0C34Cb_I_ptfVmEhefncz74UiGmg6Uq9iPm3rUAeXWKK5SdSkBiKjhqEawADErGQVOHLLo8AcZw6l8DqhUeuoVS8JQWd-dX2tj6xWGlQwvtg4CBbYiI/s1600/Percentage.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="219" data-original-width="620" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilF8QDJL_ha9QAKav1M0C34Cb_I_ptfVmEhefncz74UiGmg6Uq9iPm3rUAeXWKK5SdSkBiKjhqEawADErGQVOHLLo8AcZw6l8DqhUeuoVS8JQWd-dX2tj6xWGlQwvtg4CBbYiI/s400/Percentage.PNG" width="400" /></a></div>
<br />
I guess now I need to identify my next achievement!<br />
<br />
And onto the next 1,000!<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-23982015136058505442018-07-12T07:06:00.002+12:002018-07-12T07:06:30.013+12:00Certificates : Displaying errorsQuite often, you can't connect to an SSL site because .NET will tell you that the certificate is invalid.<br />
<br />
This openssl command shows you the certificate errors:<br />
<br />
<i>openssl s_client -connect company.co.nz:443|openssl x509 -text</i><br />
<br />
The output looks like:<br />
<br />
depth=2 CN = Company Root CA<br />
<i>verify error:num=19:self signed certificate in certificate chain</i><br />
Certificate:<br />
Data:<br />
Version: 3 (0x2)<br />
Serial Number:<br />
1f:06:eb:c1:00:34:00:05:56:38<br />
...<br />
<br />
etc.<br />
<br />
It also checks the intermediate and root CA certificate validation chain.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-41153519997816741092018-07-06T07:32:00.002+12:002018-07-06T07:32:51.961+12:00Certificates : The remote certificate is invalid according to the validation procedureI see this error so many times. It is generally on the client side as part of the .NET framework.<br />
<br />
The root cause of this is:<br />
<ul>
<li>Your server certificate is self-signed</li>
<li>You are using an incorrect host name to connect</li>
<li>Your certificate is not trusted</li>
</ul>
<div>
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.</div>
<div>
<br /></div>
<div>
If the certificate is not trusted, you can add it to the "Trusted Root Certification Authorities". But be mindful of security.</div>
<div>
<br /></div>
<div>
I find it useful to <a href="https://blogs.msdn.microsoft.com/jpsanders/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is-invalid-according-to-the-validation-procedure/">log</a> why .NET doesn't like it.</div>
<div>
<br /></div>
<div>
Just in case that article disappears, I've saved the config <a href="https://gist.github.com/nzpcmad/6f2592fb6275c2f3ff4fd628c7db8b43">here</a>.</div>
<div>
<br /></div>
<div>
<b>Key info:</b></div>
<div>
<br /></div>
The Network Service account must be able to write to this log so give the account access to the directory. <div>
<br /></div>
<div>
Change the log location.<div>
<br /></div>
<div>
<i>e.g. initializeData="c:\Logs\Trace.log"</i><div>
<br /></div>
<div>
<br /></div>
<div>
Now assume that company.com is not in the DNS and you have an IP address e.g. 124.40.60.80.</div>
<div>
<br /></div>
<div>
Now the URL is 124.40.60.80 but the certificate subject name is company.com. Bingo. You get the error.</div>
<div>
<br /></div>
<div>
The solution is to create a host file entry.</div>
<div>
<br /></div>
<div>
124.40.60.80 company.com</div>
<div>
<br /></div>
<div>
Now you can browse to company.com and the name will match.</div>
<div>
<br /></div>
<div>
Enjoy!</div>
<div>
<br /></div>
</div>
</div>
nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-73984852568909596272018-07-06T06:41:00.003+12:002018-07-06T06:42:15.683+12:00Visual Studio : You need to find somefile.cs to view the sourceDebugging through some socket code and suddenly the debugger came up with the above when I tried to step into the .NET code.<br />
<br />
It was asking for NetworkStream.cs , Socket.cs etc.<br />
<br />
Trying to browse to the file wasn't helping.<br />
<br />
So Mr. Google to the rescue.<br />
<br />
The solution is:<br />
<br />
<i>Visual Studio / Tools / Options / Debugging / General / Enable source server support</i><br />
<br />
Problem solved.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-26535891738169850162018-07-03T06:40:00.004+12:002018-07-03T06:40:45.664+12:00C# : The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnlyBusy doing some work with a SQL component.<br />
<br />
To check all was well, I set VS to break-point on all CLR exceptions and suddenly it came up with the above error.<br />
<br />
WTF?<br />
<br />
Lots of discussions with Mr. Google and the usual ton of garbage but then I found <a href="https://jack-vanlightly.com/blog/2016/11/15/new-sqlconnection-the-requested-performance-counter-is-not-a-custom-counter">this</a>.<br />
<br />
Run "cmd" as admin.<br />
<br />
<i>cd C:\Windows\Inf\.NET Data Provider for SqlServer</i><div>
<i><br /></i></div>
<div>
<i>lodctr _dataperfcounters_shared12_neutral.ini</i><br /><br />That did the trick.</div>
<div>
<br /></div>
<div>
BTW, lodctr "allows you to register or save performance counter name and registry settings in a file and designate trusted services".</div>
<div>
<br /></div>
<div>
Enjoy!</div>
<div>
<br /></div>
nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-67359840722693525032018-07-02T07:03:00.002+12:002018-07-02T07:09:15.244+12:00log4net: Why are all logs written to when I invoke just one?I was trying to get log4net working and I wanted 3 logs:<br />
<br />
<ul>
<li>Console</li>
<li>Text file</li>
<li>Event log</li>
</ul>
So the config. looked like:<br />
<blockquote class="tr_bq">
root<br />
!--level value="ALL" /<br />
appender-ref ref="ConsoleLog" /<br />
appender-ref ref="Log" /<br />
appender-ref ref="EventLog" /--<br />
/root</blockquote>
and then e.g.:<br />
<blockquote class="tr_bq">
appender name="ConsoleLog" type="log4net.Appender.ColoredConsoleAppender"<br />
mapping<br />
level value="ERROR" /<br />
foreColor value="White" /<br />
backColor value="Red, HighIntensity" /<br />
/mapping<br />
layout type="log4net.Layout.PatternLayout"<br />
conversionPattern value="%date [%thread] %level %logger - %message%newline"/<br />
/layout<br />
/appender </blockquote>
and called via e.g. :<br />
<br />
<i>private static readonly ILog LogConsole = log4net.LogManager.GetLogger("ConsoleLog"); </i><br />
<i><br /></i>
But when I tried e.g.<br />
<br />
LogConsole.Info<br />
<i><br /></i>
all three logs were invoked and all three entries were written!<br />
<br />
Turns out you need to remove the root level and use e.g.:<br />
<blockquote class="tr_bq">
logger name="ConsoleLog"<br />
level value="ALL" /<br />
appender-ref ref="ConsoleLog" /<br />
/logger</blockquote>
where the "appender-ref" points to the correct log.<br />
<br />
Then all works as expected.<br />
<br />
Note: angle brackets removed for display purposes!<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-32668868971142298442018-06-20T15:43:00.002+12:002018-06-20T15:44:15.255+12:00Auth0 playgroundAuth0 have a neat <a href="https://auth0.github.io/playground/">playground</a> where you can play around with the Lock settings.<br />
<br />
Lock is the Auth0 login component.<br />
<br />
I was trying to get some extra fields added when the user wants to self-register and we want to capture some extra information.<br />
<br />
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.<br />
<br />
As usual, the gist is <a href="https://gist.github.com/nzpcmad/58384013b67153098e0071f227f007bd">here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKmF6okAD00TFruZ-0fz_aAHJ_gRK8uxrPJ7jKloLz8wmCaFKArLecln8kdCXMZk0eI3XB6OQTu163pWnEUlMAQoBGeutNwCfXknKsaVZQvkHp70W5omPffq9MT1s0ILSu79J7/s1600/Screen+Shot+06-20-18+at+03.34+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="647" data-original-width="400" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKmF6okAD00TFruZ-0fz_aAHJ_gRK8uxrPJ7jKloLz8wmCaFKArLecln8kdCXMZk0eI3XB6OQTu163pWnEUlMAQoBGeutNwCfXknKsaVZQvkHp70W5omPffq9MT1s0ILSu79J7/s400/Screen+Shot+06-20-18+at+03.34+PM.PNG" width="246" /></a></div>
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpbijTglFstpPC9LHVoOWimCN5mjh7QkUVf0R5SKQo5Obfhx7_oMX8J_tq1ym0lDmF9ron4PftGwiCbli4xwt5vi4xGFIILjhdsy30Lg7lV6vpZebjwvI9H8aJyw1I7u5XIa3o/s1600/Screen+Shot+06-20-18+at+03.37+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="872" data-original-width="400" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpbijTglFstpPC9LHVoOWimCN5mjh7QkUVf0R5SKQo5Obfhx7_oMX8J_tq1ym0lDmF9ron4PftGwiCbli4xwt5vi4xGFIILjhdsy30Lg7lV6vpZebjwvI9H8aJyw1I7u5XIa3o/s400/Screen+Shot+06-20-18+at+03.37+PM.PNG" width="182" /></a></div>
<br />
Here is the signup screen. Clicking "United States" shows the drop-down. Also notice the checkbox at the bottom.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4R26Hf__1h-X056Ng4I9sSDyHVbIV9XlrvO3PC_NKJHPWgMYqpgX8t22VAvIddfFOd97_CmW-GZNbS2e3FQ7toMG0YoAB8Tq0_soVQUAeGvqSqUjX7Useh7J0TF_daCpPGFF/s1600/Screen+Shot+06-20-18+at+03.37+PM+001.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="237" data-original-width="350" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4R26Hf__1h-X056Ng4I9sSDyHVbIV9XlrvO3PC_NKJHPWgMYqpgX8t22VAvIddfFOd97_CmW-GZNbS2e3FQ7toMG0YoAB8Tq0_soVQUAeGvqSqUjX7Useh7J0TF_daCpPGFF/s400/Screen+Shot+06-20-18+at+03.37+PM+001.PNG" width="400" /></a></div>
<br />
Shortening the text shows the error message that is part of the validation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh70Suo9gnFHrRVu9ClkUSg-p0cwsKSbAexecsOyTF5GbfxScTJqKt-MX47eQJOqVbuwLcSQUcVflzmv83CEZPRJBjOIiLkFzZ7vdRMVNlHG08OGD7lMuWqZlSoWnZCmT5-81XG/s1600/Screen+Shot+06-20-18+at+03.38+PM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="746" data-original-width="400" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh70Suo9gnFHrRVu9ClkUSg-p0cwsKSbAexecsOyTF5GbfxScTJqKt-MX47eQJOqVbuwLcSQUcVflzmv83CEZPRJBjOIiLkFzZ7vdRMVNlHG08OGD7lMuWqZlSoWnZCmT5-81XG/s400/Screen+Shot+06-20-18+at+03.38+PM.PNG" width="213" /></a></div>
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-60368218187772788122018-05-16T15:03:00.000+12:002018-05-16T15:30:11.248+12:00ADFS : Cookies, tokens and timeoutsThis is for Server 2016 (ADFS 4.0).<br />
<br />
I've been helping a customer get to the bottom of token timeouts, sessions timeouts etc.<br />
<br />
The two best links I've found are:<br />
<br />
<a href="https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/ad-fs-single-sign-on-settings">AD FS Single Sign-On Settings</a><br />
<br />
<a href="https://blog.msresource.net/2016/07/07/active-directory-federation-services-adfs-single-sign-on-sso-and-token-lifetime-settings/">Active Directory Federation Services (#ADFS) Single Sign On (SSO) and token lifetime settings</a><br />
<br />
and a few lines in:<br />
<br />
<a href="https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-faq">AD FS Frequently Asked Questions (FAQ)</a><br />
<br />
that are:<br />
<br />
"<b>How long are ADFS tokens valid? </b><br />
<br />
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 <a href="https://technet.microsoft.com/en-us/windows-server-docs/identity/ad-fs/operations/ad-fs-2016-single-sign-on-settings">here</a>. <br />
<br />
The default lifetimes of the various cookies and tokens are listed below (as well as the parameters that govern the lifetimes): <br />
<br />
<b>Registered Devices </b><br />
<br />
PRT and SSO cookies: 90 days maximum, governed by PSSOLifeTimeMins. (Provided device is used at least every 14 days, which is controlled by DeviceUsageWindow)<br />
<br />
Refresh token: calculated based on the above to provide consistent behavior <br />
<br />
access_token: 1 hour by default, based on the relying party <br />
<br />
id_token: same as access token<br />
<br />
<b>Un-registered Devices</b> <br />
<br />
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. <br />
<br />
Refresh token: 8 hours by default. 24 hours with KMSI enabled <br />
<br />
access_token: 1 hour by default, based on the relying party <br />
<br />
id_token: same as access token"<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
The first issue is that of persistent cookies.<br />
<br />
<i>Set-AdfsProperties –EnablePersistentSso </i><boolean><i><br /></i><br />
These are not enabled for unregistered devices. You can turn them on with the KMSI (Keep Me Signed In) option.<br />
<br />
<i>Set-AdfsProperties -EnableKmsi $true</i><br />
<br />
What you now see in a PC browser is:</boolean><br />
<br />
<pre></pre>
<pre><code class="lang-powershell"></code></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7tT4Sys0H2SbhAoBfvIG_uHQytibkzG1-FDb6IjFF0EKEPjNyPqEh65o1pznwfiqqWBtXrv9isMuKEVBeuT-dIVDjWHQtByG-P8cr1jmZH1Bqp3q1l27pkRfKub9FojfJ_osk/s1600/Screen+Shot+05-16-18+at+10.54+AM.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="400" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7tT4Sys0H2SbhAoBfvIG_uHQytibkzG1-FDb6IjFF0EKEPjNyPqEh65o1pznwfiqqWBtXrv9isMuKEVBeuT-dIVDjWHQtByG-P8cr1jmZH1Bqp3q1l27pkRfKub9FojfJ_osk/s400/Screen+Shot+05-16-18+at+10.54+AM.PNG" width="400" /></a></div>
<pre><code class="lang-powershell">
</code></pre>
and indeed the cookies are now persistent if you tick the box.<br />
<br />
The defaults have changed from 8 hours to 24 as above.<br />
<br />
However, on some mobile devices, the onload.js has a:<br />
<br />
<i>style="display:none"</i><br />
<br />
which means that it does not display and you are back to square one.<br />
<br />
This may be because there is a:<br />
<br />
<i>"&prompt=login"</i><br />
<br />
in the query string,<br />
<br />
So assuming <b>KMSI is on</b>, you have:<br />
<br />
access token = id-token = 1 hour<br />
<br />
SSO cookie = refresh token = 24 hours<br />
<br />
To change the default:<br />
<br />
<i>Set-AdfsProperties – KmsiLifetimeMins int32</i><br />
<br />
and if <b>KMSI is off</b>:<br />
<br />
access token = id-token = 1 hour<br />
<br />
SSO cookie = refresh token = 8 hours<br />
<br />
To change the default:<br />
<br />
<i>Set-AdfsProperties –SsoLifetime int32<int32> </int32></i><br />
<br />
Also note that there is a KMSI "user component" (which adds the box) and a KMSI "ADFS feature" (that changes the timeout values). <br />
<br />
You don't want the refresh token to time out because that would force the user to re-authenticate.<br />
<br />
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.<br />
<br />
The tokens are "brand new" e.g the id-token will be valid for another hour.<br />
<br />
By a "new set", I mean an access token, a refresh token and an id-token.<br />
<br />
You get the same behaviour if you call the refresh endpoint.<br />
<br />
However, I noticed that although the value of the refresh token is different, it has the same<br />
<br />
<i>"refresh_token_expires_in": 72186</i><br />
<br />
value (adjusted by the time it took to do the refresh itself).<br />
<br />
So the new refresh token inherits the old "time to timeout".<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-80968074324526976792018-04-24T09:49:00.001+12:002018-04-24T09:49:49.344+12:00Stackoverflow : How to treat newbiesJoel Spolsky is writing a series of articles on the evolution of <a href="https://www.joelonsoftware.com/2018/04/06/the-stack-overflow-age/">stackoverflow</a>.<br />
<br />
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.<br />
<br />
Jon Skeet wrote an <a href="https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/">excellent post</a> on how to ask a question.<br />
<br />
The problem arises when they don't know enough to do that.<br />
<br />
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".<br />
<br />
Now, the standard response on stackoverflow is to close this - too broad - not focused - not a programming question.<br />
<br />
All of which is true and this question could also go on serverfault.<br />
<br />
But that doesn't help the newbie.<br />
<br />
My approach is to say something like:<br />
<br />
"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".<br />
<br />
Then I ask what IDP they plan to use?<br />
<br />
And depending on that, I may have some more suggestions or links to a good post.<br />
<br />
The outcome is that the newbie has something concrete to go on.<br />
<br />
(I leave the admin. to other people). <br />
<br />
In fact, that's how this blog originally started.<br />
<br />
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.<br />
<br />
The other point is that I can't do their job for them. All I can do is point them in the right direction.<br />
<br />
The comments section in stackoverflow is for further questions.<br />
<br />
Enjoy!<br />
<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com8tag:blogger.com,1999:blog-11195359.post-45910985236479928662018-03-29T10:55:00.003+13:002018-03-29T10:55:45.788+13:00Certificates : Removing a certificate store folderI created the wrong folder using makecert and you can't remove it using "mmc".<br />
<br />
Then I found this <a href="http://www.digitallycreated.net/Blog/58/removing-a-windows-system-certificate-store">post</a>.<br />
<br />
<i>void Main()<br />{<br /> int CERT_SYSTEM_STORE_LOCATION_SHIFT = 16;<br /> uint CERT_SYSTEM_STORE_CURRENT_USER_ID = 1;<br /> uint CERT_SYSTEM_STORE_LOCAL_MACHINE_ID = 2;<br /> <br /> uint CERT_STORE_DELETE_FLAG = 0x10; <br /> uint CERT_SYSTEM_STORE_CURRENT_USER = CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT;<br /> uint CERT_SYSTEM_STORE_LOCAL_MACHINE = CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT;<br /> <br /> CertUnregisterSystemStore("makecert", CERT_STORE_DELETE_FLAG | CERT_SYSTEM_STORE_CURRENT_USER);<br />}<br /><br />[DllImport("crypt32.dll", CharSet = CharSet.Unicode)]<br />public static extern bool CertUnregisterSystemStore(string systemStore, uint flags); </i><br />
<br />
Also need to add:<br />
<br />
<i>using System.Runtime.InteropServices;</i><br />
<br />
and run in LINQPad as a "C# program".<br />
<br />
Works for "Current User" but doesn't seem to work for "Local Computer".<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-77501336020972414532018-03-20T08:08:00.000+13:002018-03-20T08:08:42.097+13:00Certificates : Getting the thumbprint via OpenSSLI've been looking at AWS Cognito and keep coming across interesting snippets of how to do things.<br />
<br />
Let's say you wanted the ADFS thumbprint for the SSL certificate.<br />
<br />
You could do this via mmc or via the ADFS wizard or via the IIS binding.<br />
<br />
You could also do:<br />
<br />
<i>openssl s_client -showcerts -connect my-adfs:443</i><br />
<br />
Note: You just use the top-level ADFS URL - don't add /adfs/ls etc.<br />
<br />
This displays:<br />
<br />
<i>Loading 'screen' into random state - done<br />CONNECTED(000005DC)<br />depth=0 CN = my-adfs<br />verify error:num=18:self signed certificate<br />verify return:1<br />depth=0 CN = my-adfs<br />verify return:1<br />---<br />Certificate chain<br /> 0 s:/CN=my-adfs<br /> i:/CN=my-adfs<br />-----BEGIN CERTIFICATE-----<br />MIIExD...vLMng0<br />-----END CERTIFICATE-----<br />---<br />Server certificate<br />subject=/CN=my-adfs<br />issuer=/CN=my-adfs<br />---<br />No client certificate CA names sent<br />---<br />SSL handshake has read 1964 bytes and written 447 bytes<br />---<br />New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384<br />Server public key is 4096 bit<br />Secure Renegotiation IS supported<br />Compression: NONE<br />Expansion: NONE<br />SSL-Session:<br /> Protocol : TLSv1.2<br /> Cipher : ECDHE-RSA-AES256-GCM-SHA384<br /> Session-ID: 29140000...E4D79A337F1F0BBC9<br /><br /> Session-ID-ctx:<br /> Master-Key: 91E8...DE30CD<br /> Key-Arg : None<br /> PSK identity: None<br /> PSK identity hint: None<br /> SRP username: None<br /> Start Time: 1521150875<br /> Timeout : 300 (sec)<br /> Verify return code: 18 (self signed certificate)<br />---<br />read:errno=10054</i><br />
<br />
Copy / paste this section:<br />
<br />
<i>-----BEGIN CERTIFICATE-----<br />MIIExD...vLMng0<br />-----END CERTIFICATE-----</i><br />
<br />
into a file called e.g. adfs.cer<br />
<br />
Then:<br />
<br />
<i>openssl x509 -in c:\xxx\adfs.cer -fingerprint -noout</i><br />
<br /><i>SHA1 Fingerprint=24:F8:...:9A:21:2B:35 </i><br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-69904106990167971042018-03-13T15:55:00.000+13:002018-03-13T16:01:25.309+13:00SAML : Decoding the SAML responseI've blogged before about this and I normally use the SAML Tracer running under Firefox.<br />
<br />
Someone asked me about AWS Cognito and while I was having a look at this and doing some troubleshooting, I came across a page that also showed you how you can do this with PowerShell.<br />
<br />
Basically, in your trace find the "SAML Response".<br />
<br />
Then copy / paste it into:<br />
<br />
<i>[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("base64encodedtext"))</i><br />
<br />
so something like:<br />
<br />
PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64Strin<br />
g("PHNhbWxwO2...c2FtbHA6UmVzcG9uc2U+"))<br />
<br />
<pre style="background-color: white; margin: 0em; overflow: auto;"><code style="color: black; font-family: "consolas" , "courier new" , "courier" , monospace; font-size: 10pt;"><samlp:Response ID=<span style="color: #a31515;">"_f560b...9cf8c7d"</span> Version=<span style="color: #a31515;">"2.0"</span> IssueIn
stant=<span style="color: #a31515;">"2018-03-13T02:13:05.625Z"</span> Destination=<span style="color: #a31515;">"https://signin.aws.amazon.com/saml
"</span> Consent=<span style="color: #a31515;">"urn:oasis:names:tc:SAML:2.0:consent:unspecified"</span> xmlns:samlp=<span style="color: #a31515;">"urn:oas
is:names:tc:SAML:2.0:protocol"</span>>...</Assertion></samlp:Response></code></pre>
<br />
Neat!<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com0tag:blogger.com,1999:blog-11195359.post-91978258316921971112018-02-14T13:46:00.000+13:002018-02-14T13:46:58.653+13:00ADFS : MSIS9642: The request cannot be completed This is for Server 2016 (ADFS 4.0).<br />
<br />
The full error is:<br />
<br />
<i>MSIS9642: The request cannot be completed because an id token is required but the server was unable to construct an id token for the current user.</i><br />
<br />
You only get this error if you are using OpenID Connect with ADAL configured via Application Groups.<br />
<br />
Our setup is:<br />
<br />
User --> application --> external ADFS A --> internal ADFS B via HRD<br />
<br />
We had used this model no problem with OWIN OIDC applications authenticating on both the internal and external ADFS.<br />
<br />
However, on the applications that used ADAL, external authentication worked fine but trying the internal one threw the above error.<br />
<br />
ADFS A is set up as a CP to ADFS B.<br />
<br />
There's a good write-up <a href="https://stackoverflow.com/questions/35295260/adfs-openid-connect-email-claim-and-external-adfs">here</a>.<br />
<br />
"The root cause of MSIS9642 is that the new OpenID Connect Application Group features in ADFS 2016 need to issue an access token to your application. This token must include the users identity. In order to issue the token the subsystem must understand which claim in the inbound claims is used to uniquely identify the user. <br />
<br />
A new property called AnchorClaimType has been added to the Claim Provider Trust model."<br />
<br />
Note that this property is <b>not available</b> on a RP trust.<br />
<br />
The PowerShell needs to be run on the CP server i.e. ADFS A.<br />
<br />
(Get-AdfsClaimsProviderTrust -Name "CP name").anchorclaimtype<br />
<br />
This will be blank the first time. You can use any attribute that makes sense to uniquely identify the user. Typically, this would be sAMAccountName or UPN.<br />
<br />
In our case, we had a custom claim so the command was:<br />
<br />
<i>Set-AdfsClaimsProviderTrust -TargetName "CP Trust" -AnchorClaimType "http://company/claims<br />/sAMAccountname"</i><br />
<br />
and you can check this is correct by running the above Get-AdfsClaimsProviderTrust command again.<br />
<br />
Remember that you need to pass-through this claim in the CP claims rules and the RP claims rules.<br />
<br />
Enjoy!<br />
<br />nzpcmadhttp://www.blogger.com/profile/06352759009406963230noreply@blogger.com1