INSERT INTO sites(host) VALUES('') 2002: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) 网站价值¥52,503(不含域名),MYIP.CN网站综合数据统计 - 域名,Alexa,PR,反向链接,关键字
  测网速 网站优化诊断 广告招商QQ3066631932 CodeForge最好的源码站!   手机测速 测速APP



sponsored links:
sponsored links:


网站估价:  (注:不包含域名价值,不代表公司价值)


Google Page Rank:
真假PR鉴别:   (提示:若此处显示网站与查询网站不同,则疑为劫持PR)
Sogou Rank:






Name Server:
Whois Server:

Alexa 排名走势数据

流量统计: 当日 一周平均 三个月平均




Alexa 排名走势图

Alexa Reach走势图

域名 Whois 记录

Who is at

% The data in the WHOIS database of 1&1 Internet AG is provided by

% 1&1 for information purposes, and to assist persons in obtaining

% information about or related to a domain name registration record.

% 1&1 does not guarantee its accuracy. By submitting a WHOIS query,

% you agree that you will use this data only for lawful purposes and that,

% under no circumstances, you will use this data to

% (1) allow, enable, or otherwise support the transmission by e-mail,

% telephone, or facsimile of mass, unsolicited, commercial advertising or

% solicitations to entities other than the data recipient's own existing

% customers; or

% (2) enable high volume, automated, electronic processes that send queries or

% data to the systems of any Registry Operator or ICANN-Accredited registrar,

% except as reasonably necessary to register domain names or modify existing

% registrations.

% 1&1 reserves the right to modify these terms at any time.

% By submitting this query, you agree to abide by this policy.


created: 26-May-2002

last-changed: 27-May-2010

registration-expiration: 26-May-2011





registrant-lastname: Baier

registrant-street1: Kurfuersten-Anlage 61

registrant-pcode: 69115

registrant-city: Heidelberg

registrant-ccode: DE

registrant-phone: +49.6214018830

registrant-email: dbaier


admin-c-lastname: Baier

admin-c-street1: Kurfuersten-Anlage 61

admin-c-pcode: 69115

admin-c-city: Heidelberg

admin-c-ccode: DE

admin-c-phone: +49.6214018830

admin-c-email: dbaier


tech-c-lastname: EINSUNDEINS

tech-c-organization: 1&1 Internet AG

tech-c-street1: Brauerstr. 48

tech-c-pcode: 76135

tech-c-city: Karlsruhe

tech-c-ccode: DE

tech-c-phone: +49.721913747660

tech-c-fax: +49.72191374246



bill-c-lastname: EINSUNDEINS

bill-c-organization: 1&1 Internet AG

bill-c-street1: Brauerstr. 48

bill-c-pcode: 76135

bill-c-city: Karlsruhe

bill-c-ccode: DE

bill-c-phone: +49.721913747660

bill-c-fax: +49.72191374246


% See for information about 1&1 Internet AG


sponsored links:


国内Ping速度测试      国内TraceRoute路由测试
美国Ping速度测试      美国TraceRoute路由测试

网站关键字指数 (越高越热门)

域名 leastprivilege 其他后缀注册情况   查看更多

后缀 注册时间 到期时间 是否注册




Description: { float:left; clear:left; width:68%; background:#FFFFFF; margin-right:15px; margin-bottom:20px; margin-left: 1px; border:1px dotted #333; } #links { float:right; clear:right; width:27%; background:#FF9933; padding:15px; border:1px dotted #FFF; } .blog { padding:15px; background:#FFF; } .blogbody { font-family:verdana, arial, sans-serif; color:#666666; font-size:11px; font-weight:normal; background:#FFFFFF; line-height:14px; padding:10px; } .body { font-family:verdana, arial, sans-serif; color:#666666; font-size:11px; font-weight:normal; background:#FFFFFF; line-height:14px; padding:10px; } .title { font-family: verdana, arial; font-size: 15px; color: #003366; text-transform:uppercase; } .footer { font-family:verdana, arial, sans-serif; color:#666; font-size:10px; font-weight:normal; background:#fff; line-height:14px; padding:10px; border-top:1px dotted #6C6457; } .editorialLink { font-family:verdana, arial, sans-serif; font-size:10px; font-weight:normal; background:#FF9933; } #menu { margin-bottom:15px; background:#FFFFFF; text-align:center; } .date { font-family:verdana, arial, sans-serif; font-size: 11px; color: #666666; font-weight:bold; border-bottom:1px solid #999; margin-bottom:10px; } .FreeTextboxStyle { color: #000000; } .posted { font-family:verdana, arial, sans-serif; font-size: 11px; color: #003366; margin-bottom:25px; } .pageTopic { padding-bottom: 5px; font-size: 12pt; font-family: Georgia; font-weight: bold; } .side { font-family:verdana, arial, sans-serif; color:#333333; font-size:11px; font-weight:normal; background:#FF9933; line-height:14px; padding:2px; } .sidetitle { font-family:verdana, arial, sans-serif; color:#FFF; font-size:11px; font-weight:normal; line-height:14px; padding:2px; margin-top:10px; letter-spacing: .1em; border-bottom:1px dotted #FFF; text-align:center; background:#FF9933; } .hCalendarStyle, .dCalendarStyle { font-family:verdana, arial, sans-serif; border:1px dotted #FFF; } .hCalendarMonthYearRow, .dCalendarMonthYearRow { color:#FFFFFF; font-size:10px; font-weight:bold; line-height:14px; padding:2px; text-align:center; width:100%; background:#6C6457; } .hCalendarMonthYearRow td, .dCalendarMonthYearRow td { color:#FFFFFF; } .hCalendarNextPrevStyle a, .dCalendarNextPrevStyle a { color:#FFFFFF; } .hCalendarNextPrevStyle a:visited, .dCalendarNextPrevStyle a:visited { color:#FFFFFF; } .hCalendarDayNameRow, .dCalendarDayNameRow { color:#993300; font-size:10px; font-weight:bold; line-height:14px; padding:2px; } .hCalendarDay a, .dCalendarDay a { color:#FFFFFF; } .hCalendarDay a:visited, .dCalendarDay a:visited { color:#000000; } .hCalendarDayLinked, .dCalendarDayLinked { color:#666; background-color: #D6802A; font-size:10px; font-weight:normal; line-height:14px; padding:2px; } .hCalendarDayCurrent, .dCalendarDayCurrent { color:#FFFFFF; background-color: #993300; font-weight:normal; line-height:14px; } .hCalendarDayCurrent a, .dCalendarDayCurrent a { color:#FFFFFF; } .hCalendarDayCurrent a:visited, .dCalendarDayCurrent a:visited { color:#000000; } td { font-family:verdana, arial, sans-serif; color:#666666; font-size:12px; font-weight:normal; line-height:14px; } .blogRollNestedOutlineBodyTableStyle { margin-left: 25px; } .categoryListNestedOutlineBodyTableStyle { width:100%; margin-left:9px; margin-bottom:4px; } .blogRollDescriptionStyle { font-weight:normal; font-size:7pt; margin-left:15px; }
dominick baier on .net, security and other stuff
Permanent Links
Starter STS
ASP.NET InfoCardSelector
Custom Basic Authentication for IIS
Developing more-secure Microsoft ASP.NET Applications
Meet me at
Software Architect
For Your Favourites
FX Security
Microsoft Deutschland Security Portal
Security in Whidbey
Tools for Thinktecture
Whidbey General
Work in Progress
Sign In
Tuesday, 01 March 2011
Adding a Certificate to the Root Certificate Store from the Command Line (e.g. as an Azure Startup Task)The title says it all ;) certutil -addstore root LeastPrivilegeCA.cerAzure
Tuesday, 01 March 2011 14:25:16 UTC
Friday, 25 February 2011
Windows Phone 7 and WS-TrustA question that I often hear these days is: “Can I connect a Windows Phone 7 device to my existing enterprise services?”. Well – since most of my services are typically issued token based, this requires support for WS-Trust and WS-Security on the client. Let’s see what’s necessary to write a WP7 client for this scenario. First I converted the Silverlight library that comes with the Identity Training Kit to WP7. Some things are not supported in WP7 WCF (like message inspectors and some client runtime hooks) – but besides that this was a simple copy+paste job. Very nice! Next I used the WSTrustClient to request tokens from my STS: private WSTrustClient GetWSTrustClient(){ var client = new WSTrustClient( new WSTrustBindingUsernameMixed(), new EndpointAddress("…/issue.svc/mixed/username"), new UsernameCredentials(_txtUserName.Text, _txtPassword.Password)); return client;} private void _btnLogin_Click(object sender, RoutedEventArgs e){ _client = GetWSTrustClient(); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer) { AppliesTo = new EndpointAddress("") }; _client.IssueCompleted += client_IssueCompleted; _client.IssueAsync(rst);} I then used the returned RSTR to talk to the WCF service. Due to a bug in the combination of the Silverlight library and the WP7 runtime – symmetric key tokens seem to have issues currently. Bearer tokens work fine. So I created the following binding for the WCF endpoint specifically for WP7.font face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"font style="font-size: 11pt" lt;fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"customBindingfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" gt;brbrfontspanfontfontfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"brspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"bindingfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#ff0000"namefontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"=fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"mixedNoSessionBearerBinaryfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"securityfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#ff0000"authenticationModefontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"=fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"IssuedTokenOverTransportfontspanfontfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""
fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#ff0000"messageSecurityVersionfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"=fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanfontfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"WSSecurity11
BasicSecurityProfile10fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"issuedTokenParametersfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#ff0000"keyTypefontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"=fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"BearerKeyfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000""fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" / gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;/fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"securityfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"binaryMessageEncodingfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" / gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"httpsTransportfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"/ gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;/fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"bindingfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"
spanfontfont face="Consolas"font style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff" lt;/fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515"customBindingfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#0000ff" gt;fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"span
The binary encoding is not necessary, but will speed things up a little for mobile devices.
I then call the service with the following code:font face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"font style="font-size: 11pt"privatefontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"voidfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" _btnCallService_Click(fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"objectfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" sender, RoutedEventArgs e)fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font face="Consolas"font style="font-size: 11pt" color="#000000"{fontfontspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"varfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" binding = fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" CustomBinding(fontspanfontfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" BinaryMessageEncodingBindingElement(),fontspanfontfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" HttpsTransportBindingElement());fontspanfontfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"spanfont span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font face="Consolas"font style="font-size: 11pt" color="#000000" fontfontspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" _proxy = fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" StarterServiceContractClient(fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font face="Consolas"font style="font-size: 11pt" color="#000000" binding,fontfontspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" EndpointAddress(fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#a31515""…"fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000"));fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font face="Consolas"font style="font-size: 11pt" color="#000000" fontfontspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"usingfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" (fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"varfontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000" scope = fontspanspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" OperationContextScope(_proxy.InnerChannel))fontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font face="Consolas"font style="font-size: 11pt" color="#000000" {fontfontspanfont face="Consolas"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#000000"font style="font-size: 11pt" OperationContext.Current.OutgoingMessageHeaders.Add(fontfontspanfont style="font-size: 11pt"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font color="#0000ff"newfontspanfontspan style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" color="#000000" IssuedTokenHeader(Globals.RSTR));fontspanfontfont face="Consolas"font color="#000000"span style="font-family: ; color: ; mso-ansi-language: en-us" lang="EN-US"font style="font-size: 11pt" fontspanspan style="font-family: ; color: "font style="font-size: 11pt"_proxy.GetClaimsAsync();fontspanfontfontspan style="font-family: ; color: "font face="Consolas"font style="font-size: 11pt" color="#000000" }fontfontspan}
Friday, 25 February 2011 08:35:12 UTC
Tuesday, 15 February 2011
Windows CardSpace ndash;R.I.P.
Tuesday, 15 February 2011 17:51:15 UTC
Monday, 31 January 2011
DevWeek 2011Grats to Nick for the biggest DevWeek ever! Looking forward to it!Conferences
Monday, 31 January 2011 07:12:36 UTC
Wednesday, 26 January 2011
Get your annual reality check ‘nuff said – be there ;)Conferences
Wednesday, 26 January 2011 06:10:58 UTC
Friday, 21 January 2011
Thinktecture.IdentityModel is now available from NuGetYou can add my WIF helper library now via NuGet. Simply type “Install-Package Thinktecture.IdentityModel” into the Package Manager Console. Or use the “Add Library Package Reference” dialog.IdentityModel
Friday, 21 January 2011 10:56:47 UTC
Monday, 10 January 2011
StarterSTS 1.5 is now officially powered by Windows Azure…and will be released soon ;) IdentityModel
Monday, 10 January 2011 21:16:21 UTC
Thursday, 30 December 2010
Windows Azure Root CAs and SSL Client CertificatesI ran into some problems while trying to make SSL client certificates work for StarterSTS 1.5. In theory you have to do two things (via startup tasks): Unlock the SSL section in IIS Install all the root certificates for the client certs you want to accept I did that. But it still does not work. While inspecting the event log, I stumbled over an schannel error message that I’ve never seen before: “When asking for client authentication, this server sends a list of trusted certificate authorities to the client. The client uses this list to choose a client certificate that is trusted by the server. Currently, this server trusts so many certificate authorities that the list has grown too long. This list has thus been truncated. The administrator of this machine should review the certificate authorities trusted for client authentication and remove those that do not really need to be trusted.” WTF? And indeed standard Azure (web role) VMs trust 275 root CAs (see attached list). Including kinda obscure ones. I don’t really know why MS made this design decision. It seems just wrong (including breaking the SSL client cert functionality). Deleting like 60% of them made SSL client certs from my CA work. So I guess I now have to find an automated way to attach CTLs to my site…joy. Exported list of trusted CA (as of 30th Dec 2010)AC Raíz Certicámara S.A. (4/2/2030 9:42:02 PM)AC RAIZ FNMT-RCM (1/1/2030 12:00:00 AM)A-CERT ADVANCED (10/23/2011 2:14:14 PM)Actalis Authentication CA G1 (6/25/2022 2:06:00 PM)Agence Nationale de Certification Electronique (8/12/2037 9:03:17 AM)Agence Nationale de Certification Electronique (8/12/2037 9:58:14 AM)Agencia Catalana de Certificacio (NIF Q-0801176-I) (1/7/2031 10:59:59 PM)America Online Root Certification Authority 1 (11/19/2037 8:43:00 PM)America Online Root Certification Authority 2 (9/29/2037 2:08:00 PM)ANCERT Certificados CGN (2/11/2024 5:27:12 PM)ANCERT Certificados Notariales (2/11/2024 3:58:26 PM)ANCERT Corporaciones de Derecho Publico (2/11/2024 5:22:45 PM)A-Trust-nQual-01 (11/30/2014 11:00:00 PM)A-Trust-nQual-03 (8/17/2015 10:00:00 PM)A-Trust-Qual-01 (11/30/2014 11:00:00 PM)A-Trust-Qual-02 (12/2/2014 11:00:00 PM)A-Trust-Qual-03a (4/24/2018 10:00:00 PM)Austria Telekom-Control Kommission (9/24/2005 12:40:00 PM)Austrian Society for Data Protection (2/12/2009 11:30:30 AM)Austrian Society for Data Protection GLOBALTRUST Certification Service (9/18/2036 2:12:35 PM)Autoridad Certificadora Raiz de la Secretaria de Economia (5/9/2025 12:00:00 AM)Autoridad de Certificacion de la Abogacia (6/13/2030 10:00:00 PM)Autoridad de Certificacion Firmaprofesional CIF A62634068 (10/24/2013 10:00:00 PM)Autoridade Certificadora Raiz Brasileira (11/30/2011 11:59:00 PM)Baltimore CyberTrust Root (5/12/2025 11:59:00 PM)BIT AdminCA-CD-T01 (1/25/2016 12:36:19 PM)BIT Admin-Root-CA (11/10/2021 7:51:07 AM)Buypass Class 2 CA 1 (10/13/2016 10:25:09 AM)Buypass Class 3 CA 1 (5/9/2015 2:13:03 PM)CA Disig (3/22/2016 1:39:34 AM)CertEurope (3/27/2037 11:00:00 PM)CERTICAMARA S.A. (2/23/2015 5:10:37 PM)Certicámara S.A. (5/23/2011 10:00:00 PM)Certigna (6/29/2027 3:13:05 PM)Certipost E-Trust Primary Normalised CA (7/26/2020 10:00:00 AM)Certipost E-Trust Primary Qualified CA (7/26/2020 10:00:00 AM)Certipost E-Trust Primary TOP Root CA (7/26/2025 10:00:00 AM)Certisign Autoridade Certificadora AC1S (6/27/2018 12:00:00 AM)Certisign Autoridade Certificadora AC2 (6/27/2018 12:00:00 AM)Certisign Autoridade Certificadora AC3S (7/9/2018 8:56:32 PM)Certisign Autoridade Certificadora AC4 (6/27/2018 12:00:00 AM)CertPlus Class 1 Primary CA (7/6/2020 11:59:59 PM)CertPlus Class 2 Primary CA (7/6/2019 11:59:59 PM)CertPlus Class 3 Primary CA (7/6/2019 11:59:59 PM)CertPlus Class 3P Primary CA (7/6/2019 11:59:59 PM)CertPlus Class 3TS Primary CA (7/6/2019 11:59:59 PM)CertRSA01 (3/3/2010 2:59:59 PM)certSIGN Root CA (7/4/2031 5:20:04 PM)Certum (6/11/2027 10:46:39 AM)Certum Trusted Network CA (12/31/2029 12:07:37 PM)Chambers of Commerce Root - 2008 (7/31/2038 12:29:50 PM)Chambersign Chambers of Commerce Root (9/30/2037 4:13:44 PM)Chambersign Global Root (9/30/2037 4:14:18 PM)Chambersign Public Notary Root (9/30/2037 4:14:49 PM)Chunghwa Telecom Co. Ltd. (12/20/2034 2:31:27 AM)Cisco Systems (5/14/2029 8:25:42 PM)CNNIC Root (4/16/2027 7:09:14 AM)Common Policy (10/15/2027 4:08:00 PM)COMODO (12/31/2028 11:59:59 PM)COMODO (1/18/2038 11:59:59 PM)COMODO (12/31/2029 11:59:59 PM)ComSign Advanced Security CA (3/24/2029 9:55:55 PM)ComSign CA (3/19/2029 3:02:18 PM)ComSign Secured CA (3/16/2029 3:04:56 PM)Correo Uruguayo - Root CA (12/31/2030 2:59:59 AM)Cybertrust Global Root (12/15/2021 8:00:00 AM)DanID (2/11/2037 9:09:30 AM)DanID (4/5/2021 5:03:17 PM)Deutsche Telekom Root CA 2 (7/9/2019 11:59:00 PM)DigiCert (11/10/2031 12:00:00 AM)DigiCert (11/10/2031 12:00:00 AM)DigiCert (11/10/2031 12:00:00 AM)DigiNotar Root CA (3/31/2025 6:19:21 PM)DIRECCION GENERAL DE LA POLICIA (2/8/2036 10:59:59 PM)DST (ABA.ECOM) CA (7/9/2009 5:33:53 PM)DST (ANX Network) CA (12/9/2018 4:16:48 PM)DST (Baltimore EZ) CA (7/3/2009 7:56:53 PM)DST (National Retail Federation) RootCA (12/8/2008 4:14:16 PM)DST (United Parcel Service) RootCA (12/7/2008 12:25:46 AM)DST ACES CA X6 (11/20/2017 9:19:58 PM)DST Root CA X3 (9/30/2021 2:01:15 PM)DST RootCA X1 (11/28/2008 6:18:55 PM)DST RootCA X2 (11/27/2008 10:46:16 PM)DSTCA E1 (12/10/2018 6:40:23 PM)DSTCA E2 (12/9/2018 7:47:26 PM)DST-Entrust GTI CA (12/9/2018 12:32:24 AM)D-TRUST GmbH (5/16/2022 5:20:47 AM)D-TRUST GmbH (6/8/2012 11:47:46 AM)D-TRUST GmbH (5/16/2022 5:20:47 AM)EBG Elektronik Sertifika Hizmet Saglayicisi (8/14/2016 12:31:09 AM)E-Certchile (9/5/2028 7:39:41 PM)Echoworx Root CA2 (10/7/2030 10:49:13 AM)ECRaizEstado (6/23/2030 1:41:27 PM)EDICOM (4/13/2028 4:24:22 PM)E-GÜVEN Elektronik Sertifika Hizmet Saglayicisi (1/4/2017 11:32:48 AM)E-ME SSI (RCA) (5/19/2027 8:48:15 AM)Entrust (11/27/2026 8:53:42 PM)Entrust (5/25/2019 4:39:40 PM) (12/7/2030 5:55:54 PM)Equifax Secure eBusiness CA-1 (6/21/2020 4:00:00 AM)Equifax Secure eBusiness CA-2 (6/23/2019 12:14:45 PM)Equifax Secure Global eBusiness CA-1 (6/21/2020 4:00:00 AM)eSign Australia: eSign Imperito Primary Root CA (5/23/2012 11:59:59 PM)eSign Australia: Gatekeeper Root CA (5/23/2014 11:59:59 PM)eSign Australia: Primary Utility Root CA (5/23/2012 11:59:59 PM)Fabrica Nacional de Moneda y Timbre (3/18/2019 3:26:19 PM)GeoTrust (8/22/2018 4:41:51 PM)GeoTrust (7/16/2036 11:59:59 PM)GeoTrust Global CA (5/21/2022 4:00:00 AM)GeoTrust Global CA 2 (3/4/2019 5:00:00 AM)GeoTrust Primary Certification Authority - G2 (1/18/2038 11:59:59 PM)GeoTrust Primary Certification Authority - G3 (12/1/2037 11:59:59 PM)GeoTrust Universal CA (3/4/2029 5:00:00 AM)GeoTrust Universal CA 2 (3/4/2029 5:00:00 AM)Global Chambersign Root - 2008 (7/31/2038 12:31:40 PM)GlobalSign (1/28/2028 12:00:00 PM)GlobalSign (12/15/2021 8:00:00 AM)Go Daddy Class 2 Certification Authority (6/29/2034 5:06:20 PM)GTE CyberTrust Global Root (8/13/2018 11:59:00 PM)GTE CyberTrust Root (4/3/2004 11:59:00 PM)GTE CyberTrust Root (2/23/2006 11:59:00 PM)Halcom CA FO (6/5/2020 10:33:31 AM)Halcom CA PO 2 (2/7/2019 6:33:31 PM)Hongkong Post Root CA (1/16/2010 11:59:00 PM)Hongkong Post Root CA 1 (5/15/2023 4:52:29 AM)I.CA První certifikacní autorita a.s. (4/1/2018 12:00:00 AM)I.CA První certifikacní autorita a.s. (4/1/2018 12:00:00 AM)InfoNotary (3/6/2026 5:33:05 PM)IPS SERVIDORES (12/29/2009 11:21:07 PM)IZENPE S.A. (1/30/2018 11:00:00 PM) (12/13/2037 8:27:25 AM)Japan Certification Services, Inc. SecureSign RootCA1 (9/15/2020 2:59:59 PM)Japan Certification Services, Inc. SecureSign RootCA11 (4/8/2029 4:56:47 AM)Japan Certification Services, Inc. SecureSign RootCA2 (9/15/2020 2:59:59 PM)Japan Certification Services, Inc. SecureSign RootCA3 (9/15/2020 2:59:59 PM)Japan Local Government PKI Application CA (3/31/2016 2:59:59 PM)Japanese Government ApplicationCA (12/12/2017 3:00:00 PM)Juur-SK AS Sertifitseerimiskeskus (8/26/2016 2:23:01 PM)KamuSM (8/21/2017 11:37:07 AM)KISA RootCA 1 (8/24/2025 8:05:46 AM)KISA RootCA 3 (11/19/2014 6:39:51 AM)Macao Post eSignTrust (1/29/2013 11:59:59 PM)MicroSec e-Szigno Root CA (4/6/2017 12:28:44 PM)Microsoft Authenticode(tm) Root (12/31/1999 11:59:59 PM)Microsoft Root Authority (12/31/2020 7:00:00 AM)Microsoft Root Certificate Authority (5/9/2021 11:28:13 PM)Microsoft Timestamp Root (12/30/1999 11:59:59 PM)MOGAHA Govt of Korea (4/21/2012 9:07:23 AM)MOGAHA Govt of Korea GPKI (3/15/2017 6:00:04 AM)NetLock Arany (Class Gold) Fotanúsítvány (12/6/2028 3:08:21 PM)NetLock Expressz (Class C) Tanusitvanykiado (2/20/2019 2:08:11 PM)NetLock Kozjegyzoi (Class A) Tanusitvanykiado (2/19/2019 11:14:47 PM)NetLock Minositett Kozjegyzoi (Class QA) Tanusitvanykiado (12/15/2022 1:47:11 AM)NetLock Platina (Class Platinum) Fotanúsítvány (12/6/2028 3:12:44 PM)NetLock Uzleti (Class B) Tanusitvanykiado (2/20/2019 2:10:22 PM)Netrust CA1 (3/30/2021 2:57:45 AM)Network Solutions (12/31/2029 11:59:59 PM)NLB Nova Ljubljanska Banka d.d. Ljubljana (5/15/2023 12:22:45 PM)OISTE WISeKey Global Root GA CA (12/11/2037 4:09:51 PM)Post.Trust Root CA (7/5/2022 9:12:33 AM)Post.Trust Root CA (8/20/2010 1:56:21 PM)Posta CA Root (10/20/2028 12:52:08 PM)POSTarCA (2/7/2023 11:06:58 AM)QuoVadis Root CA 2 (11/24/2031 6:23:33 PM)QuoVadis Root CA 3 (11/24/2031 7:06:44 PM)QuoVadis Root Certification Authority (3/17/2021 6:33:33 PM)Root CA Generalitat Valenciana (7/1/2021 3:22:47 PM)RSA Security 2048 V3 (2/22/2026 8:39:23 PM)SECOM Trust Systems CO LTD (6/6/2037 2:12:32 AM)SECOM Trust Systems CO LTD (6/25/2019 10:23:48 PM)SECOM Trust Systems CO LTD (9/30/2023 4:20:49 AM)Secretaria de Economia Mexico (5/8/2025 12:00:00 AM)Secrétariat Général de la Défense Nationale (10/17/2020 2:29:22 PM)SecureNet CA Class B (10/16/2009 9:59:00 AM)Serasa Certificate Authority I (11/21/2024 2:12:45 PM)Serasa Certificate Authority II (11/21/2024 12:44:48 PM)Serasa Certificate Authority III (11/21/2024 1:24:14 PM)SERVICIOS DE CERTIFICACION - A.N.C. (3/9/2009 9:08:07 PM)Sigen-CA (6/29/2021 9:57:46 PM)Sigov-CA (1/10/2021 2:22:52 PM)Skaitmeninio sertifikavimo centras (12/28/2026 12:05:04 PM)Skaitmeninio sertifikavimo centras (12/25/2026 12:08:26 PM)Skaitmeninio sertifikavimo centras (12/22/2026 12:11:30 PM)Sonera Class1 CA (4/6/2021 10:49:13 AM)Sonera Class2 CA (4/6/2021 7:29:40 AM)Spanish Property amp; Commerce Registry CA (4/27/2012 9:39:50 AM)Staat der Nederlanden Root CA (12/16/2015 9:15:38 AM)Staat der Nederlanden Root CA - G2 (3/25/2020 11:03:10 AM)Starfield Class 2 Certification Authority (6/29/2034 5:39:16 PM)Starfield Technologies (6/26/2019 12:19:54 AM)Starfield Technologies Inc. (12/31/2029 11:59:59 PM)StartCom Certification Authority (9/17/2036 7:46:36 PM)S-TRUST Authentication and Encryption Root CA 2005:PN (6/21/2030 11:59:59 PM)Swisscom Root CA 1 (8/18/2025 10:06:20 PM)SwissSign (10/25/2036 8:30:35 AM)SwissSign Platinum G2 Root CA (10/25/2036 8:36:00 AM)SwissSign Silver G2 Root CA (10/25/2036 8:32:46 AM)TC TrustCenter Class 1 CA (1/1/2011 11:59:59 AM)TC TrustCenter Class 2 CA (1/1/2011 11:59:59 AM)TC TrustCenter Class 2 CA II (12/31/2025 10:59:59 PM)TC TrustCenter Class 3 CA (1/1/2011 11:59:59 AM)TC TrustCenter Class 3 CA II (12/31/2025 10:59:59 PM)TC TrustCenter Class 4 CA (1/1/2011 11:59:59 AM)TC TrustCenter Class 4 CA II (12/31/2025 10:59:59 PM)TC TrustCenter Time Stamping CA (1/1/2011 11:59:59 AM)TC TrustCenter Universal CA I (12/31/2025 10:59:59 PM)TC TrustCenter Universal CA II (12/31/2030 10:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte (7/16/2036 11:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte (12/31/2020 11:59:59 PM)thawte Primary Root CA - G2 (1/18/2038 11:59:59 PM)thawte Primary Root CA - G3 (12/1/2037 11:59:59 PM)Thawte Timestamping CA (12/31/2020 11:59:59 PM)Trustis EVS Root CA (1/9/2027 11:56:00 AM)Trustis FPS Root CA (1/21/2024 11:36:54 AM)Trustwave (1/1/2035 5:37:19 AM)Trustwave (12/31/2029 7:40:55 PM)Trustwave (12/31/2029 7:52:06 PM)TURKTRUST Elektronik Islem Hizmetleri (9/16/2015 12:13:05 PM)TURKTRUST Elektronik Islem Hizmetleri (3/22/2015 10:04:51 AM)TURKTRUST Elektronik Sertifika Hizmet Saglayicisi (9/16/2015 10:07:57 AM)TURKTRUST Elektronik Sertifika Hizmet Saglayicisi (3/22/2015 10:27:17 AM)TÜRKTRUST Elektronik Sertifika Hizmet Saglayicisi (12/22/2017 6:37:19 PM)TW Government Root Certification Authority (12/5/2032 1:23:33 PM)TWCA Root Certification Authority 1 (12/31/2030 3:59:59 PM)TWCA Root Certification Authority 2 (12/31/2030 3:59:59 PM)U.S. Government FBCA (10/6/2010 6:53:56 PM)UCA Global Root (12/31/2037 12:00:00 AM)UCA Root (12/31/2029 12:00:00 AM)USERTrust (7/9/2019 6:40:36 PM)USERTrust (7/9/2019 5:36:58 PM)USERTrust (6/24/2019 7:06:30 PM)USERTrust (7/9/2019 6:19:22 PM)USERTrust (5/30/2020 10:48:38 AM)UTN - USERFirst-Network Applications (7/9/2019 6:57:49 PM)ValiCert Class 3 Policy Validation Authority (6/26/2019 12:22:33 AM)VAS Latvijas Pasts SSI(RCA) (9/13/2024 9:27:57 AM)VeriSign (5/18/2018 11:59:59 PM)VeriSign (7/16/2036 11:59:59 PM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (12/31/1999 9:37:48 AM)VeriSign (1/7/2004 11:59:59 PM)VeriSign (5/18/2018 11:59:59 PM)VeriSign (1/7/2004 11:59:59 PM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (1/7/2020 11:59:59 PM)VeriSign (12/31/1999 9:35:58 AM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (7/16/2036 11:59:59 PM)VeriSign (1/7/2004 11:59:59 PM)VeriSign (7/16/2036 11:59:59 PM)VeriSign (1/7/2010 11:59:59 PM)VeriSign (5/18/2018 11:59:59 PM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (1/7/2004 11:59:59 PM)VeriSign (7/16/2036 11:59:59 PM)VeriSign (7/16/2036 11:59:59 PM)VeriSign (8/1/2028 11:59:59 PM)VeriSign (5/18/2018 11:59:59 PM)VeriSign Class 3 Public Primary CA (8/1/2028 11:59:59 PM)VeriSign Class 3 Public Primary Certification Authority - G4 (1/18/2038 11:59:59 PM)VeriSign Time Stamping CA (1/7/2004 11:59:59 PM)VeriSign Universal Root Certification Authority (12/1/2037 11:59:59 PM)Visa eCommerce Root (6/24/2022 12:16:12 AM)Visa Information Delivery Root CA (6/29/2025 5:42:42 PM)VRK Gov. Root CA (12/18/2023 1:51:08 PM)Wells Fargo Root Certificate Authority (1/14/2021 4:41:28 PM)WellsSecure Public Certificate Authority (12/14/2022 12:07:54 AM)Xcert EZ by DST (7/11/2009 4:14:18 PM)Azure
Thursday, 30 December 2010 10:21:18 UTC
Wednesday, 29 December 2010
Windows Azure Diagnostics: Next to Useless?To quote my good friend Christian: “Tracing is probably one of the most discussed topics in the Windows Azure world. Not because it is freaking cool – but because it can be very tedious and partly massively counter-intuitive.” lt;rant gt; The .NET Framework has this wonderful facility called TraceSource. You define a named trace and route that to a configurable listener. This gives you a lot of flexibility – you can create a single trace file – or multiple ones. There is even nice tooling around that. SvcTraceViewer from the SDK let’s you open the XML trace files – you can filter and sort by trace source and event type, aggregate multiple files…blablabla. Just what you would expect from a decent tracing infrastructure. Now comes Windows Azure. I was already very grateful that starting with the SDK 1.2 we finally had a way to do tracing and diagnostics in the cloud (kudos!). But the way the Azure DiagnosticMonitor is currently implemented – could be called flawed. The Azure SDK provides a DiagnosticsMonitorTraceListener – which is the right way to go. The only problem is, that way this works is, that all traces (from all sources) get written to an ETW trace. Then the DiagMon listens to these traces and copies them periodically to your storage account. So far so good. But guess what happens to your nice trace files: the trace source names get “lost”. They appear in your message text at the end. So much for filtering and sorting and aggregating (regex #fail or #win??). Every trace line becomes an entry in an Azure Storage Table – the svclog format is gone. So much for the existing tooling. To solve that problem, one workaround was to write your own trace listener (!) that creates svclog files inside of local storage and use the DiagMon to copy those. Christian has a blog post about that. OK done that. Now it turns out that this mechanism does not work anymore in 1.3 with FullIIS (see here). Quoting: “Some IIS 7.0 logs not collected due to permissions issues...The root cause to both of these issues is the permissions on the log files.” And the workaround: “To read the files yourself, log on to the instance with a remote desktop connection.” Now then have fun with your multi-instance deployments…. So the bottom line is, that currently you cannot copy IIS logs, FREB logs and everything else that gets written by W3WP. Nice… lt;/rant gt;Azure
Wednesday, 29 December 2010 11:53:50 UTC
Tuesday, 28 December 2010
Unlocking the SSL Section in Windows Azure Web RolesPosting the favourite command line snippet seems to be the newest hobby for Azure developers ;) Here’s one that is useful to unlock the SSL section (e.g. for client certificates):%windir%\System32\inetsrv\appcmd.exe unlock config /section:system.webServer/security/accessbrAzure
Tuesday, 28 December 2010 20:52:25 UTC
Saturday, 25 December 2010
Handling Configuration Changes in Windows Azure ApplicationsWhile finalizing StarterSTS 1.5, I had a closer look at lifetime and configuration management in Windows Azure. (this is no new information – just some bits and pieces compiled at one single place – plus a bit of reality check) When dealing with lifetime management (and especially configuration changes), there are two mechanisms in Windows Azure – a RoleEntryPoint derived class and a couple of events on the RoleEnvironment class. You can find good documentation about RoleEntryPoint here. The RoleEnvironment class features two events that deal with configuration changes – Changing and Changed. Whenever a configuration change gets pushed out by the fabric controller (either changes in the settings section or the instance count of a role) the Changing event fires. The event handler receives an instance of the RoleEnvironmentChangingEventArgs type. This contains a collection of type RoleEnvironmentChange. This in turn is a base class for two other classes that detail the two types of possible configuration changes I mentioned above: RoleEnvironmentConfigurationSettingsChange (configuration settings) and RoleEnvironmentTopologyChange (instance count). The two respective classes contain information about which configuration setting and which role has been changed. Furthermore the Changing event can trigger a role recycle (aka reboot) by setting EventArgs.Cancel to true. So your typical job in the Changing event handler is to figure if your application can handle these configuration changes at runtime, or if you rather want a clean restart. Prior to the SDK 1.3 VS Templates – the following code was generated to reboot if any configuration settings have changed:private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e){ // If a configuration setting is changing if (e.Changes.Any(change = gt; change is RoleEnvironmentConfigurationSettingChange)) { // Set e.Cancel to true to restart this role instance e.Cancel = true; }} This is a little drastic as a default since most applications will work just fine with changed configuration – maybe that’s the reason this code has gone away in the 1.3 SDK templates (more). The Changed event gets fired after the configuration changes have been applied. Again the changes will get passed in just like in the Changing event. But from this point on RoleEnvironment.GetConfigurationSettingValue() will return the new values. You can still decide to recycle if some change was so drastic that you need a restart. You can use RoleEnvironment.RequestRecycle() for that (more). As a rule of thumb: When you always use GetConfigurationSettingValue to read from configuration (and there is no bigger state involved) – you typically don’t need to recycle. In the case of StarterSTS, I had to abstract away the physical configuration system and read the actual configuration (either from web.config or the Azure service configuration) at startup. I then cache the configuration settings in memory. This means I indeed need to take action when configuration changes – so in my case I simply clear the cache, and the new config values get read on the next access to my internal configuration object. No downtime – nice! GotchaA very natural place to hook up the RoleEnvironment lifetime events is the RoleEntryPoint derived class. But with the move to the full IIS model in 1.3 – the RoleEntryPoint methods get executed in a different AppDomain (even in a different process) – see here.. You might no be able to call into your application code to e.g. clear a cache. Keep that in mind! In this case you need to handle these events from e.g. global.asax.Azure
Saturday, 25 December 2010 06:46:54 UTC
Friday, 24 December 2010
Update to DeployManagerRaf did some updates to his tool. It can now generate WIF/WCF certificateReference sections. Nice. Blog post: link: DeployManager.exeTools
Friday, 24 December 2010 09:50:26 UTC
Thursday, 02 December 2010
5000 Downloads of StarterSTSnice ;) thanks for all the feedback and testing! IdentityModel
Thursday, 02 December 2010 16:25:37 UTC
Sunday, 14 November 2010
TechEd 2010 ndash;Architecting Claims-aware ApplicationsBack from TechEd – was a blast ;) Here’s the recording of my talk:
Sunday, 14 November 2010 17:34:21 UTC
Sunday, 31 October 2010
StarterSTS v1.5 Beta 1I just uploaded a new drop of StarterSTS. This release has many changes and new features, e.g.: Built-in support for Windows Azure Caching New REST endpoint Federated Sign-Out Extended tracing (including real time tracing to a WCF service and logging of RST(R)s and tokens) I will drill deeper into the new features in the forthcoming blog posts. Please try it out and give me feedback. IdentityModel
Sunday, 31 October 2010 09:34:37 UTC
Thursday, 28 October 2010
WIF, ADFS 2 and WCF ndash;Part 6: Chaining multiple Token ServicesSee the previous posts first. So far we looked at the (simpler) scenario where a client acquires a token from an identity provider and uses that for authentication against a relying party WCF service. Another common scenario is, that the client first requests a token from an identity provider, and then uses this token to request a new token from a Resource STS or a partner’s federation gateway. This sounds complicated, but is actually very easy to achieve using WIF’s WS-Trust client support. The sequence is like this: Request a token from an identity provider. You use some “bootstrap” credential for that like Windows integrated, UserName or a client certificate. The realm used for this request is the identifier of the Resource STS/federation gateway. Use the resulting token to request a new token from the Resource STS/federation gateway. The realm for this request would be the ultimate service you want to talk to. Use this resulting token to authenticate against the ultimate service. Step 1 is very much the same as the code I have shown in the last post. In the following snippet, I use a client certificate to get a token from my STS:private static SecurityToken GetIdPToken(){ var factory = new WSTrustChannelFactory( new CertificateWSTrustBinding(SecurityMode.TransportWithMessageCredential, idpEndpoint); factory.TrustVersion = TrustVersion.WSTrust13; factory.Credentials.ClientCertificate.SetCertificate( StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=Client"); var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointAddress(rstsRealm), KeyType = KeyTypes.Symmetric }; var channel = factory.CreateChannel(); return channel.Issue(rst);} To use a token to request another token is slightly different. First the IssuedTokenWSTrustBinding is used and second the channel factory extension methods are used to send the identity provider token to the Resource STS:private static SecurityToken GetRSTSToken(SecurityToken idpToken){ var binding = new IssuedTokenWSTrustBinding(); binding.SecurityMode = SecurityMode.TransportWithMessageCredential; var factory = new WSTrustChannelFactory( binding, rstsEndpoint); factory.TrustVersion = TrustVersion.WSTrust13; factory.Credentials.SupportInteractive = false; var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointAddress(svcRealm), KeyType = KeyTypes.Symmetric }; factory.ConfigureChannelFactory(); var channel = factory.CreateChannelWithIssuedToken(idpToken); return channel.Issue(rst);} For this particular case I chose an ADFS endpoint for issued token authentication (see part 1 for more background). Calling the service now works exactly like I described in my last post. You may now wonder if the same thing can be also achieved using configuration only – absolutely. But there are some gotchas. First of all the configuration files becomes quite complex. As we discussed in part 4, the bindings must be nested for WCF to unwind the token call-stack. But in this case svcutil cannot resolve the first hop since it cannot use metadata to inspect the identity provider. This binding must be supplied manually. The other issue is around the value for the realm/appliesTo when requesting a token for the R-STS. Using the manual approach you have full control over that parameter and you can simply use the R-STS issuer URI. Using the configuration approach, the exact address of the R-STS endpoint will be used. This means that you may have to register multiple R-STS endpoints in the identity provider. Another issue you will run into is, that ADFS does only accepts its configured issuer URI as a known realm by default. You’d have to manually add more audience URIs for the specific endpoints using the ADFS Powershell commandlets. I prefer the “manual” approach. That’s it. Hope this is useful information.
Thursday, 28 October 2010 10:03:58 UTC
Thursday, 14 October 2010
WIF, ADFS 2 and WCF ndash;Part 5: Service Client (more Flexibility with WSTrustChannelFactory)See the previous posts first. WIF includes an API to manually request tokens from a token service. This gives you more control over the request and more flexibility since you can use your own token caching scheme instead of being bound to the channel object lifetime. The API is straightforward. You first request a token from the STS and then use that token to create a channel to the relying party service. I’d recommend using the WS-Trust bindings that ship with WIF to talk to ADFS 2 – they are pre-configured to match the binding configuration of the ADFS 2 endpoints. The following code requests a token for a WCF service from ADFS 2:private static SecurityToken GetToken(){ // Windows authentication over transport security var factory = new WSTrustChannelFactory( new WindowsWSTrustBinding(SecurityMode.Transport), stsEndpoint); factory.TrustVersion = TrustVersion.WSTrust13; var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointAddress(svcEndpoint), KeyType = KeyTypes.Symmetric }; var channel = factory.CreateChannel(); return channel.Issue(rst);} Afterwards, the returned token can be used to create a channel to the service. Again WIF has some helper methods here that make this very easy:private static void CallService(SecurityToken token){ // create binding and turn off sessions var binding = new WS2007FederationHttpBinding( WSFederationHttpSecurityMode.TransportWithMessageCredential); binding.Security.Message.EstablishSecurityContext = false; // create factory and enable WIF plumbing var factory = new ChannelFactory lt;IService gt;(binding, new EndpointAddress(svcEndpoint)); factory.ConfigureChannelFactory lt;IService gt;(); // turn off CardSpace - we already have the token factory.Credentials.SupportInteractive = false; var channel = factory.CreateChannelWithIssuedToken lt;IService gt;(token); channel.GetClaims().ForEach(c = gt; Console.WriteLine("{0}\n {1}\n {2} ({3})\n", c.ClaimType, c.Value, c.Issuer, c.OriginalIssuer));} Why is this approach more flexible? Well – some don’t like the configuration voodoo. That’s a valid reason for using the manual approach. You also get more control over the token request itself since you have full control over the RST message that gets send to the STS. One common parameter that you may want to set yourself is the appliesTo value. When you use the automatic token support in the WCF federation binding, the appliesTo is always the physical service address. This means in turn that this address will be used as the audience URI value in the SAML token. Well – this in turn means that when you have an application that consists of multiple services, you always have to configure all physical endpoint URLs in ADFS 2 and in the WIF configuration of the service(s). Having control over the appliesTo allows you to use more symbolic realm names, e.g. the base address or a completely logical name. Since the URL is never de-referenced you have some degree of freedom here. In the next post we will look at the necessary code to request multiple tokens in a call chain. This is a common scenario when you first have to acquire a token from an identity provider and have to send that on to a federation gateway or Resource STS. Stay tuned.IdentityModel
Thursday, 14 October 2010 15:47:04 UTC
WIF, ADFS 2 and WCF ndash;Part 4: Service Client (using Service Metadata)See parts 1, 2 and 3 first. In this part we will finally build a client for our federated service. There are basically two ways to accomplish this. You can use the WCF built-in tooling to generate client and configuration via the service metadata (aka ‘Add Service Reference’). This requires no WIF on the client side. Another approach would be to use WIF’s WSTrustChannelFactory to manually talk to the ADFS 2 WS-Trust endpoints. This option gives you more flexibility, but is slightly more code to write. You also need WIF on the client which implies that you need to run on a WIF supported operating system – this rules out e.g. Windows XP clients. We’ll start with the metadata way. You simply create a new client project (e.g. a console app) – call ‘Add Service Reference’ and point the dialog to your service endpoint. What will happen then is, that VS will contact your service and read its metadata. Inside there is also a link to the metadata endpoint of ADFS 2. This one will be contacted next to find out which WS-Trust endpoints are available. The end result will be a client side proxy and a configuration file. Let’s first write some code to call the service and then have a closer look at the config file.var proxy = new ServiceClient();proxy.GetClaims().ForEach(c = gt; Console.WriteLine("{0}\n {1}\n {2} ({3})\n", c.ClaimType, c.Value, c.Issuer, c.OriginalIssuer)); That’s all. The magic is happening in the configuration file. When you in inspect app.config, you can see the following general configuration hierarchy: lt;client / gt; element with service endpoint information federation binding and configuration containing ADFS 2 endpoint 1 (with binding and configuration) ADFS 2 endpoint n (with binding and configuration) (where ADFS 2 endpoint 1…n are the endpoints I talked about in part 1) You will see a number of lt;issuer / gt; elements in the binding configuration where simply the first endpoint from the ADFS 2 metadata becomes the default endpoint and all other endpoints and their configuration are commented out. You now need to find the endpoint you want to use (based on trust version, credential type and security mode) and replace that with the default endpoint. That’s it. When you call the WCF proxy, it will inspect configuration, then first contact the selected ADFS 2 endpoint to request a token. This token will then be used to authenticate against the service. In the next post I will show you the more manual approach using the WIF APIs.IdentityModel
Thursday, 14 October 2010 13:37:16 UTC
Tuesday, 12 October 2010
WIF, ADFS 2 and WCF ndash;Part 3: ADFS SetupIn part 1 of this series I briefly gave an overview of the ADFS / WS-Trust infrastructure. In part 2 we created a basic WCF service that uses ADFS for authentication. This part will walk you through the steps to register the service in ADFS 2. I could provide screenshots for all the wizard pages here – but since this is really easy – I just go through the necessary steps in textual form. Step 1 – Select Data SourceHere you can decide if you want to import a federation metadata file that describes the service you want to register. In that case all necessary information is inside the metadata document and you are done. FedUtil (a tool that ships with WIF) can generate such metadata for the most simple cases. Another tool to create metadata can be found here. We choose ‘Manual’ here. Step 2 – Specify Display NameI guess that’s self explaining. Step 3 – Choose ProfileChoose ‘ADFS 2 Profile’ here. Step 4 – Configure CertificateRemember that we specified a certificate (or rather a private key) to be used to decrypting incoming tokens in the previous post. Here you specify the corresponding public key that ADFS 2 should use for encrypting the token. Step 5 – Configure URLThis page is used to configure WS-Federation and SAML 2.0p support. Since we are using WS-Trust you can leave both boxes unchecked. Step 6 – Configure IdentifierHere you specify the identifier (aka the realm, aka the appliesTo) that will be used to request tokens for the service. This value will be used in the token request and is used by ADFS 2 to make a connection to the relying party configuration and claim rules. Step 7 – Configure Issuance Authorization RulesHere you can configure who is allowed to request token for the service. I won’t go into details here how these rules exactly work – that’s for a separate blog post. For now simply use the “Permit all users” option. OK – that’s it. The service is now registered at ADFS 2. In the next part we will finally look at the service client. Stay tuned…IdentityModel
Tuesday, 12 October 2010 14:53:56 UTC
Monday, 11 October 2010
WIF, ADFS 2 and WCF ndash;Part 2: The ServiceOK – so let’s first start with a simple WCF service and connect that to ADFS 2 for authentication. The service itself simply echoes back the user’s claims – just so we can make sure it actually works and to see how the ADFS 2 issuance rules emit claims for the service:[ServiceContract(Namespace = "urn:leastprivilege:samples")]public interface IService{ [OperationContract] List lt;ViewClaim gt; GetClaims();}public class Service : IService{ public List lt;ViewClaim gt; GetClaims() { var id = Thread.CurrentPrincipal.Identity as IClaimsIdentity; return (from c in id.Claims select new ViewClaim { ClaimType = c.ClaimType, Value = c.Value, Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer }).ToList(); }} The ViewClaim data contract is simply a DTO that holds the claim information. Next is the WCF configuration – let’s have a look step by step. First I mapped all my http based services to the federation binding. This is achieved by using .NET 4.0’s protocol mapping feature (this can be also done the 3.x way – but in that scenario all services will be federated): lt;protocolMapping gt; lt;add scheme="http" binding="ws2007FederationHttpBinding" / gt; lt;/protocolMapping gt; Next, I provide a standard configuration for the federation binding: lt;bindings gt; lt;ws2007FederationHttpBinding gt; lt;binding gt; lt;security mode="TransportWithMessageCredential" gt; lt;message establishSecurityContext="false" gt; lt;issuerMetadata address="https://server/adfs/services/trust/mex" / gt; lt;/message gt; lt;/security gt; lt;/binding gt; lt;/ws2007FederationHttpBinding gt; lt;/bindings gt; This binding points to our ADFS 2 installation metadata endpoint. This is all that is needed for svcutil (aka “Add Service Reference”) to generate the required client configuration. I also chose mixed mode security (SSL + basic message credential) for best performance. This binding also disables session – you can control that via the establishSecurityContext setting on the binding. This has its pros and cons. Something for a separate blog post, I guess. Next, the behavior section adds support for metadata and WIF: lt;behaviors gt; lt;serviceBehaviors gt; lt;behavior gt; lt;serviceMetadata httpsGetEnabled="true" / gt; lt;federatedServiceHostConfiguration / gt; lt;/behavior gt; lt;/serviceBehaviors gt; lt;/behaviors gt; The next step is to add the WIF specific configuration (in lt;microsoft.identityModel / gt;). First we need to specify the key material that we will use to decrypt the incoming tokens. This is optional for web applications but for web services you need to protect the proof key – so this is mandatory (at least for symmetric proof keys, which is the default): lt;serviceCertificate gt; lt;certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" findValue="CN=Service" / gt; lt;/serviceCertificate gt; You also have to specify which incoming tokens you trust. This is accomplished by registering the thumbprint of the signing keys you want to accept. You get this information from the signing certificate configured in ADFS 2: lt;issuerNameRegistry type="...ConfigurationBasedIssuerNameRegistry" gt; lt;trustedIssuers gt; lt;add thumbprint="d1 … db" name="ADFS" / gt; lt;/trustedIssuers gt; lt;/issuerNameRegistry gt; The last step (promised) is to add the allowed audience URIs to the configuration – WCF clients use (by default – and we’ll come back to this) the endpoint address of the service: lt;audienceUris gt; lt;add value="https://machine/soapadfs/service.svc" / gt; lt;/audienceUris gt; OK – that’s it – now we have a basic WCF service that uses ADFS 2 for authentication. The next step will be to set-up ADFS to issue tokens for this service. Afterwards we can explore various options on how to use this service from a client. Stay tuned… (if you want to have a look at the full source code or peek at the upcoming parts – you can download the complete solution here)IdentityModel
Monday, 11 October 2010 16:39:03 UTC
WIF, ADFS 2 and WCF ndash;Part 1: OverviewA lot has been written already about passive federation and integration of WIF and ADFS 2 into web apps. The whole active/WS-Trust feature area is much less documented or covered in articles and blogs. Over the next few posts I will try to compile all relevant information about the above topics – but let’s start with an overview. ADFS 2 has a number of endpoints under the /services/trust base address that implement the WS-Trust protocol. They are grouped by the WS-Trust version they support (/13 and /2005), the client credential type (/windows*, /username*, /certificate*) and the security mode (*transport, *mixed and message). You can see the endpoints in the MMC console under the Service/Endpoints page. So in other words, you use one of these endpoints (which exactly depends on your configuration / system setup) to request tokens from ADFS 2. The bindings behind the endpoints are more or less standard WCF bindings, but with SecureConversation (establishSecurityContext) disabled. That means that whenever you need to programmatically talk to these endpoints – you can (easily) create client bindings that are compatible. Another option is to use the special bindings that come with WIF (in the Microsoft.IdentityModel.Protocols.WSTrust.Bindings namespace). They are already pre-configured to be compatible with the ADFS endpoints. The downside of these bindings is, that you can’t use them in configuration. That’s definitely a feature request of mine for the next version of WIF. The next important piece of information is the so called Federation Service Identifier. This is the value that you (at least by default) have to use as a realm/appliesTo whenever you are requesting a token for ADFS (e.g. in IdP – gt; RSTS scenario). Or (even more) technically speaking, ADFS 2 checks for this value in the audience URI restriction in SAML tokens. You can get to this value by clicking the “Edit Federation Service Properties” in the MMC when the Service tree-node is selected. OK – I will come back to this basic information in the following posts. Basically I want to go through the following scenarios: ADFS in the IdP role ADFS in the R-STS role (with a chained claims provider) Using the WCF bindings for automatic token issuance Using WSTrustChannelFactory for manual token handling Stay tuned…IdentityModel
Monday, 11 October 2010 12:40:58 UTC
Wednesday, 29 September 2010
Developer minded Certificate Management ToolFellow Developer Security MVP Raffaele Rialdi just released a tool that makes common developer tasks related to certificate a little easier. His tools e.g. supports setting ACLs on private keys, copying thumbprints and generating WCF lt;identity / gt; elements. Nice work! Download here.Tools
Wednesday, 29 September 2010 05:22:49 UTC
Friday, 17 September 2010
BASTA!Wir freuen uns alle schon riesig auf die BASTA! nächste Woche in Mainz. Thinktecture ist dieses Mal vollständig vertreten und Christian, Jörg und ich haben ne nagelneue Demo-Anwendung, die wir am Freitag im Workshop zum ersten Mal öffentlich zeigen werden…spannend… Thinktecture Timetable: cuConferences
Friday, 17 September 2010 10:42:40 UTC
Sunday, 12 September 2010
StarterSTS v1.5 CTPI just uploaded a new version of StarterSTS to Codeplex. There have been some dramatic changes since the last public version, so any feedback would be appreciated. This new version is now a .NET 4.0 web application project, and includes all the necessary plumbing and configuration to deploy StarterSTS to Azure. In fact it is just a configuration change to choose between the Azure and on-premise version. Download: More info: Moving StarterSTS to the (Azure) CloudIdentityModel
Sunday, 12 September 2010 07:51:21 UTC
Saturday, 11 September 2010
Fiddler Inspector for Federation MessagesFiddler is a very useful tool for troubleshooting all kinds of HTTP(s) communications. It also features various extensibility points to make it even more useful. Using the inspector extensibility mechanism, I quickly knocked up an inspector for typical federation messages (thanks for Eric Lawrence btw). Below is a screenshot for WS-Federation. I also added support for SAML 2.0p request/response messages: The inspector can be downloaded from the identitymodel Codeplex site. Simply copy the binary to the inspector folder in the Fiddler directory.IdentityModel
Saturday, 11 September 2010 16:33:52 UTC
Saturday, 14 August 2010
Access Control Service v2A Resource-STS (others call it RP-STS or federation gateway) is a necessity for non-trivial federated identity scenarios. ADFS v2 does an excellent job in fulfilling that role – but (as of now) you have to run ADFS on-premise. The Azure Access Control Service is a Resource-STS in the cloud (with all the usual scalability/availability) promises. Unfortunately a lot of (the more interesting) features in ACS v1 had to be cut due to constrained time/resources. The good news is that ACS v2 is now in CTP and brings back a lot of the missing features (like WS* support) and adds some really sweet new ones (out of the box federation with Google, Facebook, LiveID – and OpenId in general). You can read about the details here. On a related note – ACS v2 works out of the box with StarterSTS – simply choose the ADFS v2 option and point the management portal to the StarterSTS WS-Federation metadata endpoint. Have fun ;)IdentityModel
Saturday, 14 August 2010 17:20:36 UTC
Thursday, 12 August 2010
Moving StarterSTS to the (Azure) CloudQuite some people asked me about an Azure version of StarterSTS. While I kinda knew what I had to do to make the move, I couldn’t find the time. Until recently. This blog post briefly documents the necessary changes and design decisions for the next version of StarterSTS which will work both on-premise and on Azure. ProviderFortunately StarterSTS is already based on the idea of “providers”. Authentication, roles and claims generation is based on the standard ASP.NET provider infrastructure. This makes the migration to different data stores less painful. In my case I simply moved the ASP.NET provider database to SQL Azure and still use the standard SQL Server based membership, roles and profile provider.In addition StarterSTS has its own providers to abstract resource access for certificates, relying party registration, client certificate registration and delegation. So I only had to provide new implementations. Signing and SSL keys now go in the Azure certificate store and user mappings (client certificates and delegation settings) have been moved to Azure table storage.The one thing I didn’t anticipate when I originally wrote StarterSTS was the need to also encapsulate configuration. Currently configuration is “locked” to the standard .NET configuration system. The new version will have a pluggable SettingsProvider with versions for .NET configuration as well as Azure service configuration. If you want to externalize these settings into e.g. a database, it is now just a matter of supplying a corresponding provider.Moving between the on-premise and Azure version will be just a matter of using different providers. URL HandlingAnother thing that’s substantially different on Azure (and load balanced scenarios in general) is the handling of URLs. In farm scenarios, the standard APIs like ASP.NET’s Request.Url return the current (internal) machine name, but you typically need the address of the external facing load balancer.There’s a hotfix for WCF 3.5 (included in v4) that fixes this for WCF metadata. This was accomplished by using the HTTP Host header to generate URLs instead of the local machine name. I now use the same approach for generating WS-Federation metadata as well as information card files. New FeaturesI introduced a cache provider. Since we now have slightly more expensive lookups (e.g. relying party data from table storage), it makes sense to cache certain data in the front end. The default implementation uses the ASP.NET web cache and can be easily extended to use products like memcached or AppFabric Caching.Starting with the relying party provider, I now also provide a read/write interface. This allows building management interfaces on top of this provider. I also include a (very) simple web page that allows working with the relying party provider data. I guess I will use the same approach for other providers in the future as well.I am also doing some work on the tracing and health monitoring area. Especially important for the Azure version. Stay tuned.IdentityModel
Thursday, 12 August 2010 04:21:52 UTC
Wednesday, 11 August 2010
StarterRP v1.2A small update for StarterRP is now live on codeplex. This version is based on .NET v4 and includes two sample Silverlight clients. Major update to StarterSTS coming soon…IdentityModel
Wednesday, 11 August 2010 17:16:44 UTC
Saturday, 24 July 2010
WIF, ASP.NET 4.0 and Request ValidationSince the response of a WS-Federation sign-in request contains XML, the ASP.NET built-in request validation will trigger an exception. To solve this, request validation needs to be turned off for pages receiving such a response message. Starting with ASP.NET 4.0 you can plug in your own request validation logic. This allows letting WS-Federation messages through, while applying all standard request validation to all other requests. The WIF SDK (v4) contains a sample validator that does exactly that: public class WSFedRequestValidator : RequestValidator{?xml:namespace prefix = o / protected override bool IsValidRequestString( HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) { validationFailureIndex = 0; if ( requestValidationSource == RequestValidationSource.Form amp; amp; collectionKey.Equals( WSFederationConstants.Parameters.Result, StringComparison.Ordinal ) ) { SignInResponseMessage message = WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage; if (message != null) { return true; } } return base.IsValidRequestString( context, value, requestValidationSource, collectionKey, out validationFailureIndex ); }} Register this validator via web.config: lt;httpRuntime requestValidationType="WSFedRequestValidator" / gt;IdentityModel
Saturday, 24 July 2010 08:14:36 UTC
Thursday, 22 July 2010
StarterSTS v1.2I just uploaded version 1.2 of StarterSTS. This is simply a conversion of v1.1 to a web application project. Some people have asked for it so here we go. This version is still compiled against .NET 3.5 SP1 – but this will the last release. All upcoming releases will be .NET 4.0. Codeplex Site
Thursday, 22 July 2010 09:23:30 UTC
Wednesday, 21 July 2010
IIS amp; RESTful Services #FAILreally? when will super duper IIS finally support non-Windows accounts for HTTP authentication? see here for a complete module including IIS management integration: http://custombasicauth.codeplex.comIIS | WCF
Wednesday, 21 July 2010 20:39:18 UTC
Tuesday, 20 July 2010
Re-MVP rsquo;d 2010As always: thank you Microsoft!Misc
Tuesday, 20 July 2010 05:33:43 UTC
Tuesday, 22 June 2010
Modifying the SL/WIF Integration Bits to support Issued Token CredentialsThe SL/WIF integration code that ships with the Identity Training Kit only supports Windows and UserName credentials to request tokens from an STS. This is fine for simple single STS scenarios (like a single IdP). But the more common pattern for claims/token based systems is to split the STS roles into an IdP and a Resource STS (or whatever you wanna call it). In this case, the 2nd leg requires to present the issued token from the 1st leg – this is not directly supported by the bits. But they can be easily modified to accomplish this. The CredentialFist we need a class that represents an issued token credential. Here we store the RSTR that got returned from the client to IdP request:span style="color: blue"publicspan span style="color: blue"classspan span style="color: #2b91af"IssuedTokenCredentialsspan : span style="color: #2b91af"IRequestCredentialsspanbr{br span style="color: blue"publicspan span style="color: blue"stringspan IssuedToken { span style="color: blue"getspan; span style="color: blue"setspan; }br span style="color: blue"publicspan span style="color: #2b91af"RequestSecurityTokenResponsespan RSTR { span style="color: blue"getspan; span style="color: blue"setspan; }br br span style="color: blue"publicspan IssuedTokenCredentials(span style="color: #2b91af"RequestSecurityTokenResponsespan rstr)br {br RSTR = rstr;br IssuedToken = rstr.RequestedSecurityToken.RawToken;br }br}
The BindingNext we need a binding to be used with issued token credential requests. This assumes you have an STS endpoint for mixed mode security with SecureConversation turned off.span style="color: blue"publicspan span style="color: blue"classspan span style="color: #2b91af"WSTrustBindingIssuedTokenMixedspan : span style="color: #2b91af"WSTrustBindingspanbr{br span style="color: blue"publicspan WSTrustBindingIssuedTokenMixed()br {br span style="color: blue"thisspan.Elements.Add( span style="color: blue"newspan span style="color: #2b91af"HttpsTransportBindingElementspan() );br }br}
WSTrustClientThe last step is to make some modifications to WSTrustClient to make it issued token aware. In the constructor you have to check for the credential type, and if it is an issued token, store it away.span style="color: blue"privatespan span style="color: #2b91af"RequestSecurityTokenResponsespan _rstr;brspan style="color: blue"publicspan WSTrustClient( span style="color: #2b91af"Bindingspan binding, span style="color: #2b91af"EndpointAddressspan remoteAddress, br span style="color: #2b91af"IRequestCredentialsspan credentials )br : span style="color: blue"basespan( binding, remoteAddress )br{br span style="color: blue"ifspan ( span style="color: blue"nullspan == credentials )br {br span style="color: blue"throwspan span style="color: blue"newspan span style="color: #2b91af"ArgumentNullExceptionspan( span style="color: #a31515""credentials"span );br }br br span style="color: blue"ifspan (credentials span style="color: blue"isspan span style="color: #2b91af"UsernameCredentialsspan)br {br span style="color: #2b91af"UsernameCredentialsspan usernname = credentials span style="color: blue"asspan span style="color: #2b91af"UsernameCredentialsspan;br span style="color: blue"basespan.ChannelFactory.Credentials.UserName.UserName = usernname.Username;br span style="color: blue"basespan.ChannelFactory.Credentials.UserName.Password = usernname.Password;br }br span style="color: blue"elsespan span style="color: blue"ifspan (credentials span style="color: blue"isspan span style="color: #2b91af"IssuedTokenCredentialsspan)br {br span style="color: blue"varspan issuedToken = credentials span style="color: blue"asspan span style="color: #2b91af"IssuedTokenCredentialsspan;br _rstr = issuedToken.RSTR;br }br span style="color: blue"elsespan span style="color: blue"ifspan (credentials span style="color: blue"isspan span style="color: #2b91af"WindowsCredentialsspan)br { }br span style="color: blue"elsespanbr {br span style="color: blue"throwspan span style="color: blue"newspan span style="color: #2b91af"ArgumentOutOfRangeExceptionspan(span style="color: #a31515""credentials"span, span style="color: #a31515""type was not expected"span);br }br}
Next – when WSTrustClient constructs the RST message to the STS, the issued token header must be embedded when needed:span style="color: blue"privatespan span style="color: #2b91af"Messagespan BuildRequestAsMessage( span style="color: #2b91af"RequestSecurityTokenspan request )br{br span style="color: blue"varspan message = span style="color: #2b91af"Messagespan.CreateMessage( br span style="color: blue"basespan.Endpoint.Binding.MessageVersion ?? span style="color: #2b91af"MessageVersionspan.Default,br IssueAction,br (span style="color: #2b91af"BodyWriterspan) span style="color: blue"newspan span style="color: #2b91af"WSTrustRequestBodyWriterspan( request ) );br br span style="color: blue"ifspan (_rstr != span style="color: blue"nullspan)br {br message.Headers.Add(span style="color: blue"newspan span style="color: #2b91af"IssuedTokenHeaderspan(_rstr));br }br br span style="color: blue"returnspan message;br}
Tuesday, 22 June 2010 06:45:17 UTC
Thursday, 10 June 2010
StarterSTS 1.1Earlier today I uploaded StarterSTS 1.1 and StarterRP 1.1 to codeplex. I added identity delegation for internal as well as OpenID accounts and also updated StarterRP to show these features. I also recorded an updated screencast on delegation since some of the config settings have changed since the CTP.IdentityModel
Thursday, 10 June 2010 08:07:49 UTC
Thursday, 27 May 2010
Video of Moxie Marlinspike rsquo;s ldquo;More Tricks for Defeating SSL rdquo; talk
Thursday, 27 May 2010 10:59:05 UTC
Wednesday, 26 May 2010
Updated StarterSTS Documentation amp; Identity Delegation ScreencastI recorded a short screencast describing the identity delegation feature in StarterSTS 1.1. You can watch it here. I also uploaded an updated version of the documentation here.IdentityModel
Wednesday, 26 May 2010 07:42:59 UTC
Monday, 24 May 2010
StarterSTS 1.1 CTP ndash; ActAs SupportDue to popular demand, I added identity delegation (aka ActAs) support to StarterSTS. To give this feature a try, first download the new bits and add a enableActAs = true to startersts.config. You then have to configure which user account is allowed to delegate, as well as the target realm to delegate to. This is done in usermappings.config, e.g.: lt;userMappings xmlns="" gt; lt;user name="middletier" gt; lt;mappings gt; lt;mapping type="ActAs" value="https://server/service.svc" / gt; lt;/mappings gt; lt;/user gt; lt;/users gt; lt;/userMappings gt;?xml:namespace prefix = o / Please use the forum for any feedback. thanks!IdentityModel
Monday, 24 May 2010 12:05:19 UTC
Friday, 14 May 2010
A more elegant way of embedding a SOAP security header in Silverlight 4The current situation with Silverlight is, that there is no support for the WCF federation binding. This means that all security token related interactions have to be done manually. Requesting the token from an STS is not really the bad part, sending it along with outgoing SOAP messages is what’s a little annoying. So far you had to wrap all calls on the channel in an OperationContextScope wrapping an IContextChannel. This “programming model” was a little disruptive (in addition to all the async stuff that you are forced to do). It seems that starting with SL4 there is more support for traditional WCF extensibility points – especially IEndpointBehavior, IClientMessageInspector. I never read somewhere that these are new features in SL4 – but I am pretty sure they did not exist in SL3. With the above mentioned interfaces at my disposal, I thought I have another go at embedding a security header – and yeah – I managed to make the code much prettier (and much less bizarre). Here’s the code for the behavior/inspector: public class IssuedTokenHeaderInspector : IClientMessageInspector{ RequestSecurityTokenResponse _rstr;?xml:namespace prefix = o / public IssuedTokenHeaderInspector(RequestSecurityTokenResponse rstr) { _rstr = rstr; } public void AfterReceiveReply(ref Message reply, object correlationState) { } public object BeforeSendRequest(ref Message request, IClientChannel channel) { request.Headers.Add(new IssuedTokenHeader(_rstr)); return null; }} public class IssuedTokenHeaderBehavior : IEndpointBehavior{ RequestSecurityTokenResponse _rstr; public IssuedTokenHeaderBehavior(RequestSecurityTokenResponse rstr) { if (rstr == null) { throw new ArgumentNullException(); } _rstr = rstr; } public void ApplyClientBehavior( ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(new IssuedTokenHeaderInspector(_rstr)); } // rest omitted} This allows to set up a proxy with an issued token header and you don’t have to worry anymore with embedding the header manually with every call: var client = GetWSTrustClient(); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Symmetric){ AppliesTo = new EndpointAddress("https://rp/")}; client.IssueCompleted += (s, args) = gt;{ _proxy = new StarterServiceContractClient(); _proxy.Endpoint.Behaviors.Add(new IssuedTokenHeaderBehavior(args.Result)); }; client.IssueAsync(rst); Since SL4 also support the IExtension lt;T gt; interface, you can also combine this with Nicholas Allen’s AutoHeaderExtension.IdentityModel
Friday, 14 May 2010 05:01:54 UTC
Sunday, 09 May 2010
Thinktecture.IdentityModel: WRAP and SWT SupportThe latest drop of Thinktecture.IdentityModel contains some helpers for the Web Resource Authorization Protocol (WRAP) and Simple Web Tokens (SWT). WRAPThe WrapClient class is a helper to request SWT tokens via WRAP. It supports issuer/key, SWT and SAML input credentials, e.g.: var client = new WrapClient(wrapEp);var swt = client.Issue(issuerName, issuerKey, scope);?xml:namespace prefix = o / All Issue overrides return a SimpleWebToken type, which brings me to the next helper class. SWTThe SimpleWebToken class wraps a SWT token. It combines a number of features: conversion between string format and CLR type representation creation of SWT tokens validation of SWT token projection of SWT token as IClaimsIdentity helpers to embed SWT token in headers and query strings The following sample code generates a SWT token using the helper class: private static string CreateSwtToken(){ var signingKey = "wA…"; var audience = "http://websample"; var issuer = "http://self"; var token = new SimpleWebToken( issuer, audience, Convert.FromBase64String(signingKey)); token.AddClaim(ClaimTypes.Name, "dominick"); token.AddClaim(ClaimTypes.Role, "Users"); token.AddClaim(ClaimTypes.Role, "Administrators"); token.AddClaim("simple", "test"); return token.ToString();}IdentityModel
Sunday, 09 May 2010 20:27:46 UTC
Saturday, 08 May 2010
Thinktecture.IdentityModel: Comparing Strings without leaking Timinig InformationPaul Hill commented on a recent post where I was comparing HMACSHA256 signatures. In a nutshell his complaint was that I am leaking timing information while doing so – or in other words, my code returned faster with wrong (or partially wrong) signatures than with the correct signature. This can be potentially used for timing attacks like this one. I think he got a point here, especially in the era of cloud computing where you can potentially run attack code on the same physical machine as your target to do high resolution timing analysis (see here for an example). It turns out that it is not that easy to write a time-constant string comparer due to all sort of (unexpected) clever optimization mechanisms in the CLR. With the help and feedback of Paul and Shawn I came up with this: Structure the code in a way that the CLR will not try to optimize it In addition turn off optimization (just in case a future version will come up with new optimization methods) Add a random sleep when the comparison fails (using Shawn’s and Stephen’s nice Random wrapper for RNGCryptoServiceProvider). You can find the full code in the Thinktecture.IdentityModel download. [MethodImpl(MethodImplOptions.NoOptimization)]public static bool IsEqual(string s1, string s2){ if (s1 == null amp; amp; s2 == null) { return true; }?xml:namespace prefix = o / if (s1 == null || s2 == null) { return false; } if (s1.Length != s2.Length) { return false; } var s1chars = s1.ToCharArray(); var s2chars = s2.ToCharArray(); int hits = 0; for (int i = 0; i lt; s1.Length; i++) { if (s1chars[i].Equals(s2chars[i])) { hits += 2; } else { hits += 1; } } bool same = (hits == s1.Length * 2); if (!same) { var rnd = new CryptoRandom(); Thread.Sleep(rnd.Next(0, 10)); } return same;} IdentityModel
Saturday, 08 May 2010 19:51:07 UTC
Wednesday, 05 May 2010
ADFS 2.0 RTWFinally – the identity story is complete (for now). Download ADFS 2.0.Misc
Wednesday, 05 May 2010 17:40:56 UTC
Thinktecture.IdentityModel: WIF Support for WCF REST Services and OData The latest drop of Thinktecture.IdentityModel includes plumbing and support for WIF, claims and tokens for WCF REST services and Data Services (aka OData). Cibrax has an alternative implementation that uses the WCF Rest Starter Kit. His recent post reminded me that I should finally “document” that part of our library. Features include: generic plumbing for all WebServiceHost derived WCF services support for SAML and SWT tokens support for ClaimsAuthenticationManager and ClaimsAuthorizationManager based solely on native WCF extensibility points (and WIF) This post walks you through the setup of an OData / WCF DataServices endpoint with token authentication and claims support. This sample is also included in the codeplex download along a similar sample for plain WCF REST services. Setting up the Data ServiceTo prove the point I have created a simple WCF Data Service that renders the claims of the current client as an OData set. public class ClaimsData{ public IQueryable lt;ViewClaim gt; Claims { get { return GetClaims().AsQueryable(); } }?xml:namespace prefix = o / private List lt;ViewClaim gt; GetClaims() { var claims = new List lt;ViewClaim gt;(); var identity = Thread.CurrentPrincipal.Identity as IClaimsIdentity; int id = 0; identity.Claims.ToList().ForEach(claim = gt; { claims.Add(new ViewClaim { Id = ++id, ClaimType = claim.ClaimType, Value = claim.Value, Issuer = claim.Issuer }); }); return claims; }} …and hooked that up with a read only data service: public class ClaimsDataService : DataService lt;ClaimsData gt;{ public static void InitializeService(IDataServiceConfiguration config) { config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); }} Enabling WIFBefore you enable WIF, you should generate your client proxies. Afterwards the service will only accept requests with an access token – and svcutil does not support that. All the WIF magic is done in a special service authorization manager called the FederatedWebServiceAuthorizationManager. This code checks incoming calls to see if the Authorization HTTP header (or X-Authorization for environments where you are not allowed to set the authorization header) contains a token. This header must either start with SAML access_token= or WRAP access_token= (for SAML or SWT tokens respectively). For SAML validation, the plumbing uses the normal WIF configuration. For SWT you can either pass in a SimpleWebTokenRequirement or the SwtIssuer, SwtAudience and SwtSigningKey app settings are checked.If the token can be successfully validated, ClaimsAuthenticationManager and ClaimsAuthorizationManager are invoked and the IClaimsPrincipal gets established. The service authorization manager gets wired up by the FederatedWebServiceHostFactory: public class FederatedWebServiceHostFactory : WebServiceHostFactory{ protected override ServiceHost CreateServiceHost( Type serviceType, Uri[] baseAddresses) { var host = base.CreateServiceHost(serviceType, baseAddresses); host.Authorization.ServiceAuthorizationManager = new FederatedWebServiceAuthorizationManager(); host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom; return host; }} The last step is to set up the .svc file to use the service host factory (see the sample download). Calling the ServiceTo call the service you need to somehow get a token. This is up to you. You can either use WSTrustChannelFactory (for the full CLR), WSTrustClient (Silverlight) or some other way to obtain a token. The sample also includes code to generate SWT tokens for testing – but the whole WRAP/SWT support will be subject of a separate post. I created some extensions methods for the most common web clients (WebClient, HttpWebRequest, DataServiceContext) that allow easy setting of the token, e.g.: public static void SetAccessToken(this DataServiceContext context, string token, string type, string headerName){ context.SendingRequest += (s, e) = gt; { e.RequestHeaders[headerName] = GetHeader(token, type); };} Making a query against the Data Service could look like this: static void CallService(string token, string type){ var data = new ClaimsData(new Uri("https://server/odata.svc/")); data.SetAccessToken(token, type); data.Claims.ToList().ForEach(c = gt; Console.WriteLine("{0}\n {1}\n ({2})\n", c.ClaimType, c.Value, c.Issuer));} HTHIdentityModel
Wednesday, 05 May 2010 14:54:51 UTC
Thinktecture.IdentityModel: Claims Debugger VisualizerIn the latest drop of Thinktecture.IdentityModel you can find a debugger visualizer for IClaimsIdentity and IClaimsPrincipal. Have fun ;) PS. Thanks to Mr. UI.IdentityModel
Wednesday, 05 May 2010 12:47:42 UTC
Tuesday, 27 April 2010
Sod This! ndash; reloadedOliver and Gary fortunately decided to continue with their “Sod This” podcast show. That’s good – because I always found this very entertaining. The “comeback” show is about security and identity – awesome ;)
Tuesday, 27 April 2010 10:53:55 UTC
Wednesday, 14 April 2010
Using an Active Endpoint to sign into a Web ApplicationThis question comes up from time to time, so I thought I’ll document it here. The scenario is, that you don’t want to do a passive redirect in a web app – but directly talk to an active STS endpoint to authenticate and request a token. The reasons for that could be that you need a local sign-in page in the web app – or that the token service is not publicly reachable. The following code can be used on a login page: protected void _btnLogin_Click(object sender, EventArgs e){ // authenticate with WS-Trust endpoint var factory = new WSTrustChannelFactory( new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress("https://sts/endpoint")); factory.Credentials.UserName.UserName = _txtUserName.Text; factory.Credentials.UserName.Password = _txtPassword.Text;?xml:namespace prefix = o / var channel = factory.CreateChannel(); var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointAddress("https://rp/"), KeyType = KeyTypes.Bearer }; var genericToken = channel.Issue(rst) as GenericXmlSecurityToken; // parse token var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers; var token = handlers.ReadToken(new XmlTextReader( new StringReader(genericToken.TokenXml.OuterXml))); var identity = handlers.ValidateToken(token).First(); // create session token var sessionToken = new SessionSecurityToken( ClaimsPrincipal.CreateFromIdentity(identity)); FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken); Response.Redirect("~/users/default.aspx");} IdentityModel
Wednesday, 14 April 2010 12:51:50 UTC
Tuesday, 06 April 2010
Taken by StormAny more dodgy puns? I am happy to announce that my good friend Oliver Sturm has joined thinktecture. Oliver is a brilliant computer geek in general and a language wonk in particular – good company to hang out in bars – and just generally a nice guy. Looking forward working with you!Misc
Tuesday, 06 April 2010 10:18:00 UTC
Sunday, 04 April 2010
Thinktecture StarterSTS 1.0 RTWWow – I can’t tell you how happy and relieved I am to write this post ;) I started to work with what’s now called WIF approximately two years ago – and built various security token services for customers, demos and internal use. The idea behind StarterSTS was to have a non-trivial security token service sample that demonstrates the typical tasks of an STS (where it turns out that issuing tokens is by far the smallest part) and at the same time is real world enough to be directly used in specialized situations like development STSes. I checked-in the first public version of StarterSTS at 25th May 2009 and had 1861 download so far. Today I am announcing StarterSTS 1.0 which is feature complete (and hopefully reasonably bug-free) and finally includes documentation as well as nine new screencasts on the various feature areas. I want to thank all beta-testers and early adopters that gave feedback along the way! Now that 1.0 is done we can think about ways to extend the STS in the future. Codeplex Site (main) (direct) (forum) Documentation ScreencastsInitial setup amp; configuration Federating your first web application Federating with web services Single-Sign-On amp; Confirmation screen Using the REST endpoint Using the OpenId bridge Tracing Using client certificates Using Information CardsIdentityModel
Sunday, 04 April 2010 06:33:42 UTC
Tuesday, 30 March 2010
Using Silverlight to Access WIF secured WCF Services (Part 3)In this last part of the series (see here and here) I want to show you how to use the WIF/SL integration ClaimsIdentitySessionManager to request tokens and talk to WIF secured services. The ClaimsIdentityManager registers as an ApplicationService in SL. Once registered, it can encapsulate the process of requesting a token for a relying party, caching that token as well as setting the SOAP security header for outgoing service requests. RegistrationClaimsIdentitySessionManager gets registered in app.xaml. Here you can specify the endpoint address of the WS-Trust token services as well as the credential type. In this sample I am using the ADFS2 Windows/Transport endpoint from my last post. lt;Application.ApplicationLifetimeObjects gt; lt;id:ClaimsIdentitySessionManager gt; lt;id:ClaimsIdentitySessionManager.IdentityProvider gt; lt;id:WSTrustSecurityTokenService Endpoint="https://server/services/trust/13/windowstransport" CredentialType="DefaultCredential" / gt; lt;/id:ClaimsIdentitySessionManager.IdentityProvider gt; lt;/id:ClaimsIdentitySessionManager gt; lt;/Application.ApplicationLifetimeObjects gt;?xml:namespace prefix = o / Calling the ServiceAll the service interaction is abstracted by the ClaimsIdentitySessionManager. The call to InvokeAsync does a few things: checks if a token has already been obtained for the service endpoint if not, requests the token and caches it if a password is required, invokes a callback to the UI sets the SOAP security header using the requested token private void CallService(){ var factory = new ChannelFactory lt;StarterServiceContract gt;("symmetric"); var proxy = factory.CreateChannel(); var channel = proxy as IClientChannel; ClaimsIdentitySessionManager.Current.InvokeAsync(() = gt; { proxy.BeginGetClaims(result = gt; ShowClaims(proxy, result), null); }, channel);}IdentityModel
Tuesday, 30 March 2010 08:18:07 UTC
Sunday, 28 March 2010
Requesting Tokens from ADFS2 using Silverlight and Windows AuthenticationWith SL4’s support for NTLM and the WIF integration bits, you can now easily request tokens from ADFS2 (or any other token service that supports Windows authentication) in single-sign-on style. Here’s the quick walk-through… Enable the right endpoint in ADFS2You need a WS-Trust endpoint for version 1.3 that supports transport security and Windows authentication. This endpoint needs to be enabled in the ADFS2 MMC (/trust/13/windowstransport). Configure WSTrustClient and request the TokenNext you have to configure WSTrustClient to use this endpoint, using the Windows binding and Windows credential type: var client = new WSTrustClient( new WSTrustBindingWindows(), new EndpointAddress("https://server/adfs/services/trust/13/windowstransport"), new WindowsCredentials()); From there on you can include the token to auth against other services.IdentityModel
Sunday, 28 March 2010 15:37:27 UTC
Sunday, 21 March 2010
Using Silverlight to Access WIF secured WCF Services (Part 2)This was one of my most popular blog post in the recent time (please read it first to get the necessary background information). I thought I give this another shot with the new SL/WIF integration. There are other ways to accomplish the below things, e.g. using the SL application service or passive identity providers. I am focusing here purely on the SL initiated active STS/RP communication scenario and the raw APIs. Requesting Tokens from within SilverlightIn my old post I had to use a custom REST endpoint in StarterSTS to request a bearer token. With the new WSTrustChannel, it is now possible to talk to a standard WS-Trust 1.3 endpoint (like the one in StarterSTS or ADFS2). var client = new WSTrustClient( new WSTrustBindingUsernameMixed(), new EndpointAddress("https://.../issue.svc/mixed/username"), new UsernameCredentials("username", "password"));?xml:namespace prefix = o / You then have to construct an RST. Basically you specify the key type (bearer or symmetric) and appliesTo value. var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Symmetric){ AppliesTo = new EndpointAddress("https://roadie/StarterRP/")}; The call to WSTrustClient.Issue returns an RSTR – which in turn contains the requested token and further key material. The identity kit also contains a token cache called TokenCache. You could use this class if you want to to store that token for further use. client.IssueCompleted += (s, args) = gt;{ _cache.AddTokenToCache("myRP", args.Result);}; client.IssueAsync(rst); Using a Token to authenticate with a WCF Relying PartySince Silverlight does not support issued token credentials, we must handcraft the SOAP security header. The identity kit includes the IssuedTokenHeader class for this purpose. The nice thing is, that this class supports symmetric proof keys as well as bearer tokens. But you still have to set this header manually on every call. The identity kit includes its own wrapper to abstract away the header generation. I am using my own little helper here to make this process less disruptive. public static class IssuedTokenHeaderExtensions{ public static void SendWithIssuedToken(this IContextChannel channel, RequestSecurityTokenResponse rstr, Action action) { using (new OperationContextScope(channel)) { OperationContext.Current.OutgoingMessageHeaders.Add( new IssuedTokenHeader(rstr)); action(); } }} This allows calling a WCF service like this: private void CallService(){ var factory = new ChannelFactory lt;StarterServiceContract gt;("myRP"); var proxy = factory.CreateChannel(); var channel = proxy as IContextChannel; channel.SendWithIssuedToken(_cache.GetTokenFromCache("myRP"), () = gt; { proxy.BeginGetClaims(result = gt; ShowClaims(proxy, result), null); });} The trick here again is, that the client stack is configured for no security at all, whereas the WCF service uses a federation binding (with SecureConversation turned off). I think this is pretty cool and solves some of the problems I had in the past. If Silverlight would only support client certificate credentials….IdentityModel
Sunday, 21 March 2010 20:52:58 UTC
A first Look at Silverlight and WIF IntegrationAt MIX, Caleb did a talk about the new Silverlight/WIF integration classes that “ship” with the latest identity training kit. Since this is a topic that comes up really frequently – I had a first look. The integration code consists of two projects (client amp; server side plumbing) and can be divided into several feature areas. I will post more information on the corresponding areas when I have written more code against them. Same claims programming model as in WIFThe integration code includes (I)ClaimsPrincipal, (I)ClaimsIdentity, Claim, ClaimCollection as well as the standard claim types. WS-Trust and WS-Security supportThis is my favourite feature! The WSTrustClient class allows requesting tokens from WS-Trust 1.3 endpoints. It supports Username/Password and Windows credentials as well as bearer and symmetric token types. The IssuedTokenHeader class makes it easier to embed the requested token in calls to backend services. The TokenCache class allows caching RSTRs to be used with the issued token header. Bringing claims to a Silverlight UIAnother feature area deals with bringing claims into the SL UI for personalization and authorization purposes. This needs some server side plumbing (the AuthenticationService) and seems to focus on passive scenarios. The current implementation simply mirrors the user claims that are visible in the app/service backend back to the UI. Silverlight integrationThis part of the integration code makes logons and claims access more SLish by providing an SL appplication service and thus data binding access to claims. HTHIdentityModel
Sunday, 21 March 2010 10:23:59 UTC
Tuesday, 09 March 2010
Thinktecture.DataObjectModelOur very own Jörg Neumann had this cooking for quite a while. tt.DOM is a library that lets you add features like change tracking, undo, redo, views, transactions and n-tier support to arbitrary types (or lists of types). This makes typical data scenarios in 3-tier applications *much* easier to handle. Expect more information and documentation soon (of course ;). In the meanwhile feel free to play around with it and give us feedback via the codeplex forum! http://dataobjectmodel.codeplex.comTools for Thinktecture
Tuesday, 09 March 2010 09:45:21 UTC
Sunday, 07 March 2010
This week: Trooper HeidelbergLooking forward to this week’s nice little security conference organized by my old friends at ERNW. Federated Identity - Opportunities and RisksThe world is moving towards a federated identity model. Public facing websites like Google or Facebook utilize technologies like OpenID, OAuth and WRAP to provide single-sign-on capabilities. Enterprises and ISVs start deploying WS-Federation, WS-Trust and SAML to federate with customers, partners and even internally. The goals are always the same: provide a more meaningful representation of "identity" for authentication, authorization and personalization. This talks sheds light on all these technologies, how they work and how to secure them.Conferences
Sunday, 07 March 2010 17:45:39 UTC
Friday, 05 March 2010
Guide to Claims-based Identity and Access ControlRTM finally ;) Book here.Code here.More info here. Enjoy!!!IdentityModel
Friday, 05 March 2010 12:36:46 UTC
WIF WorkshopMein geschätzter Kollege Vittorio Bertocci führt einen 2-Tägigen Workshop zum Thema Windows Identity Foundation in München durch. Das ist bestimmt eine gute Gelegenheit sich mal abseits vom Projektalltag mit dem Thema genauer zu beschäftigen. Wenn danach alle (un)Klarheiten beseitigt sind, und Sie weiterführenden Informationen oder Unterstützung zur Implementierung von Claims in der Praxis benötigen – einfach Email an mich (dominick.baier (_at_) Ich helfe gerne weiter. Viel Spaß!IdentityModel
Friday, 05 March 2010 12:28:46 UTC
Monday, 01 March 2010
Zur uuml;ck von der BASTASo – zurück und (wichtiger) erholt von der BASTA. Muss sagen – es war mal wieder sehr nett – großes Lob an Veranstalter und Teilnehmer. Hat Spaß gemacht! Am meisten war ich über das große Interesse an WIF überrascht. Ein voller Raum für nen Security Talk – und das direkt nach dem Essen ;) Hier habe ich eine sehr gute Zusammenfassung des Talks gefunden – die Punkte, die mir am Herzen lagen, scheinen angekommen zu sein! Das freut mich! Ich habe es schon während des Vortrags erwähnt – WIF ist sowohl ein neuer API als auch ein neues Paradigma. Dafür reichen 75min einfach nicht aus. Wer Fragen dazu hat, oder Unterstützung braucht – einfach Mail an mich. Bis zum nächsten Mal!Conferences
Monday, 01 March 2010 08:06:39 UTC
Adding StarterSTS as a Claims Provider for ADFS2The v1 beta of StarterSTS has an updated relying party configuration section. This allows to “plugin” the STS into ADFS2 or Sharepoint as a claims provider. Here’s a quick walkthrough for ADFS2: Register StarterSTS as claims provider in ADFSThis is really easy. Simply go to the ADFS2 configuration console and add a new claims provider. Then point the wizard to the StarterSTS WS-Federation metadata file (either by URL or using a file path). Afterwards you have to add some claim rules – to get started you could add a pass-through rule for the name claim. You will also need to export the ADFS2 certificate that is used for token decryption. Registering ADFS2 as a relying party in StarterSTSThe next step is to register ADFS2 in StarterSTS. This is done by modifying the relyingParty.config file (in the configuration sub folder). You need three things for that – the ADFS issuer URI, the physical address of the ADFS2 sign-in page and the ADFS2 token encryption certificate. The certificate could be either imported into the certificate store or you copy it to ~/App_Data/certificates. The config entry looks similar to this: lt;add realm="http:// lt;adfsname gt;/adfs/services/trust" replyTo="https:// lt;adfsname gt;/adfs/ls/" gt; lt;certificate filename="tokendecryption.cer" / gt; lt;/add gt; HTHIdentityModel
Monday, 01 March 2010 07:30:14 UTC
Friday, 19 February 2010
WCF, WIF and Load Balancing (and a bit of Azure)Pablo wrote a post yesterday giving some background information on how session tokens are protected in WIF – here some additional info for WCF: The ws* bindings in WCF establish a security session by default (via WS-SecureConversation). This has some implications, e.g. You end up with a stateful service – or more important – with a stateful programming model. You have all the typical session “problems” like faulted sessions, timeout, retries etc… By default SecureConversation only transmits a session identifier (like a ASP.NET session cookie) – the actual session is stored in-memory at the server. Not good for load balancing. When you want to use WCF in a load balanced environment (e.g Azure) – you have to change the default behavior – you basically have two options: Turn off SecureConversation all together. This has the advantage of being stateless (at least in that part of the communication). But this also means, that the bootstrap (SAML) token will get parsed on every request – this includes invoking the ClaimsAuthenticationManager. This might have performance implications – but depends on your scenario. Force WCF into “cookie mode”. This means that the complete IClaimsPrincipal (after ClaimsAuthenticationManager has run) gets serialized and round-tripped in the SOAP header. Turning off SecureConversationUnfortunately WCF 3.5 does not directly allow that on the standard federation bindings. You would need to create a custom binding that uses an authentication mode of IssuedTokenOverTransport (for mixed mode) or IssuedTokenForCertificate (for message security). In .NET 4 you can simply set establishSecurityContext to false on the standard ws-fed binding. Cookie ModeForcing WCF into cookie mode requires a custom binding. The “trick” here is to set requireSecurityContextCancellation to false – which is just a fancy name for “serialize the context into the message”. Here’s the binding I am using (mixed mode security): lt;customBinding gt; lt;binding name="federation_cookie" gt; lt;security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11 WSTrust13 WSSecureConversation13 WSSecurityPolicy12 BasicSecurityProfile10" requireSecurityContextCancellation="false" gt; lt;secureConversationBootstrap authenticationMode="IssuedTokenOverTransport" messageSecurityVersion="WSSecurity11 WSTrust13 WSSecureConversation13 WSSecurityPolicy12 BasicSecurityProfile10" gt; lt;issuedTokenParameters gt; lt;issuerMetadata address="https://…" / gt; lt;/issuedTokenParameters gt; lt;/secureConversationBootstrap gt; lt;/security gt; lt;textMessageEncoding / gt; lt;httpsTransport / gt; lt;/binding gt; lt;/customBinding gt;?xml:namespace prefix = o / As Pablo points out in his post, the session cookie must be protected somehow. The standard WIF behavior is to the DPAPI user key. This key cannot be easily shared between nodes in a cluster (unless the nodes are all domain members and roaming profiles are activated). Another more explicit (and practical) option is to use an RSA key. Most typically you would feed your SSL certificate or the certificate used to decrypt incoming tokens into the following session token handler: public class WebFarmSessionSecurityTokenHandler : SessionSecurityTokenHandler{ public WebFarmSessionSecurityTokenHandler(X509Certificate2 protectionCertificate) : base(CreateRsaTransforms(protectionCertificate)) { } private static ReadOnlyCollection lt;CookieTransform gt; CreateRsaTransforms (X509Certificate2 protectionCertificate) { var transforms = new List lt;CookieTransform gt;() { new DeflateCookieTransform(), new RsaEncryptionCookieTransform(protectionCertificate), new RsaSignatureCookieTransform(protectionCertificate), }; return transforms.AsReadOnly(); }} One way of wiring up the above handler would be a service host factory for the WIF enabled WCF service. If you want to put a little more work in it you can also make the handler configuration friendly (see here). In general I’d recommend watching Hervey’s excellent talk from PDC09 about WIF in load balanced environments (e.g. Azure). HTHIdentityModel
Friday, 19 February 2010 07:36:26 UTC
Monday, 15 February 2010
Securing WCF Data Services using WIFThis questions comes up every once in a while.. Since WCF Data Services is just a normal WCF service (using the web programming model), all the typical security APIs and extensibility points apply. That said, depending on your scenario you might have to be a little more creative for REST-style services. Here’s a quick walkthrough: Enabling WIF in the Data ServiceThe easiest way to get WIF wired up is by writing a custom service host factory. You simply have to derive from DataServiceHostFactory, override CreateServiceHost and call FederatedServiceCredentials.ConfigureServiceHost before you return the host to the plumbing. This gives you the standard WIF integration for all standard HTTP credential types (Basic, Integrated etc…) and the typical extensibility points like ClaimsAuthorizationManager. For accepting and converting more advanced token types like SWT or SAML, you need to plugin your own token handling. I gave it a try for SWT tokens (see here for the general SWT integration story). public class ProtectedDataServiceHostFactory : DataServiceHostFactory{ protected override ServiceHost CreateServiceHost( Type serviceType, Uri[] baseAddresses) { var host = base.CreateServiceHost(serviceType, baseAddresses); host.Authorization.ServiceAuthorizationManager = new SimpleWebTokenAuthorizationManager( acsAddress, expectedAudience, acsKey); host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom; return host; }} This uses my SWT plumbing to turn incoming SWT tokens into an IClaimsPrincipal. You could easily do the same thing for SAML (but be aware that SAML tokens can become quite big – and you typically want to transmit them using an HTTP header for this scenario). You could now use the resulting claims for authorization as well as WCFDS interceptors, e.g.: [QueryInterceptor("Users")]public Expression lt;Func lt;Users, bool gt; gt; OnQueryUsers(){ var principal = Thread.CurrentPrincipal as IClaimsPrincipal; var customer = principal.GetClaimValue("http://claims/customerName"); return user = gt; user.Applications.ApplicationName == customer;} Sending a token header to the Data ServiceThe next step is to send a token to the Data Service. This can be achieved by handling the SendingRequest event on the DataServiceContext derived client plumbing, e.g.: class ProviderEntitiesWithToken : ProviderEntities{ string _token; string _tokenHeader = "Authorization";?xml:namespace prefix = o / public ProviderEntitiesWithToken(Uri address, string token) : base(address) { _token = token; SendingRequest += OnSendingRequest; } void OnSendingRequest(object sender, SendingRequestEventArgs e) { e.RequestHeaders[_tokenHeader] = SimpleWebToken.GetAuthorizationHeader(_token); }} Using the Data ServiceThe usage pattern is the same as without any tokens or WIF. New up your derived class, set the token and use e.g. LINQ to query the Data Service. static void Main(string[] args){ var token = RequestToken(); var service = new ProviderEntitiesWithToken(new Uri(dataServiceAddress), token); var users = from u in service.Users select u; users.ToList().ForEach(u = gt; Console.WriteLine(u.UserName));} HTHIdentityModel
Monday, 15 February 2010 13:48:40 UTC
Monday, 08 February 2010
Integrating Simple Web Tokens (SWT) with WCF REST Services using WIFThe Simple Web Token (SWT) is a new amp; simple token format that was created by Microsoft, Google and others. See here for specs. The Azure platform App Fabric Access Control service e.g. uses this token type. Why yet another token type? Well – the advantages of SWT are that it is simple to construct (form encoded key value pairs), that only simple crypto is needed (SHA256 HMACs) and that it is compact on the wire which allows easy embedding in HTTP headers or query strings. The downsides are – it is not a widely adopted token format (current spec version is and the lack of asymmetric signatures (e.g. X.509 based). Since I had to do some ACS work recently, I crafted up a simple SWT integration for WCF based REST services (works in ASP.NET as well). The plumbing looks for a SWT token either on the Authorization or X-Authorization header as well as on the query string. Using the power of WIF, it is simple to transform the SWT token into an IClaimsPrincipal. From that point on, you have all the unified identity representation benefits of WIF. Download here.IdentityModel
Monday, 08 February 2010 14:30:41 UTC
Friday, 05 February 2010
Using SAML as a Client Credential Type in WCF (updated to WIF RTM)A reader has asked me to update the Client SAML sample to WIF RTM (for background and motivation please read here first). The main work was in the SAML security token handler Validate method, this looks now like this: public override ClaimsIdentityCollection ValidateToken(SecurityToken token){ if (token == null) { throw new ArgumentNullException("token"); } var samlToken = token as SamlSecurityToken; if (samlToken == null) { throw new ArgumentException("token"); } if (samlToken.Assertion == null) { throw new ArgumentException("token"); } var assertion = samlToken.Assertion as Saml11Assertion; this.ValidateConditions(samlToken.Assertion.Conditions, false); // extract claims from token var identity = new ClaimsIdentity("ClientSaml"); ProcessStatement(assertion.Statements, identity, "Client"); // call authentication and filtering logic IClaimsIdentity newIdentity; try { if (ValidateUser(identity, out newIdentity)) { return new ClaimsIdentityCollection(new IClaimsIdentity[] { newIdentity }); } else { throw new SecurityTokenValidationException("Authentication failed"); } } catch (Exception ex) { throw new SecurityTokenValidationException("Security token validation failed", ex); }}?xml:namespace prefix = o / You would then derive from the base handler and implement the ValidateUser method. This method does some sort of authentication based on the incoming claims and returns an IClaimsIdentity containing the claims that should get passed through to the service code, e.g.: // sample implementation - do not use for production ;)protected override bool ValidateUser(ClaimsIdentity id, out IClaimsIdentity newIdentity){ newIdentity = null; var usernameClaim = id.Claims.First(c = gt; c.ClaimType == WSIdentityConstants.ClaimTypes.Name); var passwordClaim = id.Claims.First(c = gt; c.ClaimType == _passwordClaimType); var customerIdClaim = id.Claims.First(c = gt; c.ClaimType == _customerIdClaimType); if (usernameClaim.Value == passwordClaim.Value) { newIdentity = new ClaimsIdentity(new Claim[] { usernameClaim, customerIdClaim }, "ClientSaml"); return true; } return false;} You can find the complete source code here.IdentityModel
Friday, 05 February 2010 06:44:39 UTC
Wednesday, 03 February 2010
StarterSTS V1.0 Beta 1OK – I finally was able to carve out some time…This is the first feature complete release of the StarterSTS! New features include: client certificate support for WS-Fed and WS-Trust endpoints new relying party configuration allows specifying an explicit reply to address allows relying parties without encryption refactoring of web site / STS code. Still no docs – sorry. Please contact me via the Codeplex forum if you have any questions. Some brief migration remarks: relying parties are now configured in relyingParties.config. Move the RP entries from certificates.config to this new config file userMappings.config allows mapping client certificates to membership users profile configuration has been moved to profile.config On the todo list: documentation simplified installation IIS InetMgr integration for all configuration aspects What I need from you: testers! input and feedback volunteers for completing the todos Have fun! download here:
Wednesday, 03 February 2010 21:22:22 UTC
Monday, 01 February 2010
Testing Security Code with MolesI am by far no (unit) testing expert. But I always found it odd that I sometimes have to re-structure code to make it explicitly unit-testable. One typical example is code that relies on some sort of context – e.g. Thread.CurrentPrincipal. I personally like this pattern in the .NET Framework – but it is not ideal for testing. Recently I ran across Moles which is a mocking and stubs framework from Microsoft Research which has some features that can help here. Inspired by this video – I gave it a try. The following code allows “faking” Thread.CurrentPrincipal: using System.Security.Principal;using System.Threading.Moles;using Microsoft.Moles.Framework;using Microsoft.VisualStudio.TestTools.UnitTesting;[assembly: MoledType(typeof(System.Threading.Thread))]namespace SecurityTest{ [TestClass] public class UnitTest1 { [TestMethod] [HostType("Moles")] public void TestSecurityCode() { MThread.CurrentPrincipalGet = () = gt; new GenericPrincipal(new GenericIdentity("dominick"), null); var security = new SecurityCode(); var user = security.SomeMethod(); Assert.AreEqual("dominick", user); } } public class SecurityCode { public string SomeMethod() { // simulates context Thread.CurrentPrincipal = new GenericPrincipal( new GenericIdentity("bob"), null); return Thread.CurrentPrincipal.Identity.Name; } }} ?xml:namespace prefix = o /Misc
Monday, 01 February 2010 10:36:20 UTC
A Guide to Claims-Based Identity and Access ControlGet it here!!!
Monday, 01 February 2010 07:48:16 UTC
Tuesday, 05 January 2010
Claims Identity Guide ndash; Release CandidateThe last six months we were working on finalizing the P amp;P guide to claims based identity and access control. We finally have a release candidate! Eugenio has all the details here. As always, feedback is welcome! Enjoy!IdentityModel
Tuesday, 05 January 2010 05:37:21 UTC
Thursday, 24 December 2009
Beware of WIF HTTP Modules and Default ConfigurationMost samples I know of – as well as FedUtil generated configuration set a preCondition="managedHandler" for the WIF HTTP modules. This means that the modules (and thus the protection of the requested resource) only kicks in for “managed” content like .aspx files. Not for static content like .xml etc. If you like to protect static content using WIF, you have to remove the preCondition in web.config. Also add the runAllManagedModulesForAllRequests attribute to the modules section in system.webServer if you are using ASP.NET URL Authorization. Subtle security hole…IdentityModel
Thursday, 24 December 2009 10:49:24 UTC
WIF Configuration ndash; Part 3: ExtensibilitySome of the WIF configuration elements support extensibility. This means that you can attach arbitrary XML child elements to the configuration elements. When this is the case, the WIF configuration system creates the piece of plumbing in question using a special ctor that takes an XmlNodeList representing the custom configuration. You can then parse the XML and configure the class accordingly. Examples are: IssuerNameRegistry lt;issuerNameRegistry type="ConfigurationBasedIssuerNameRegistry, ..." gt; lt;trustedIssuers gt; lt;add name="foo" thumbprint="xxx" / gt; lt;/trustedIssuers gt; lt;/issuerNameRegistry gt;?xml:namespace prefix = o / ClaimsAuthorizationManager(see here) lt;claimsAuthorizationManager type="PolicyBasedAuthorizationManager" gt; lt;policy resource="Directory" action="Browse" gt; lt;claim claimType="…" claimValue="Users" / gt; lt;/policy gt; lt;/claimsAuthorizationManager gt; SecurityTokenHandler(see here) lt;add type="Saml11SecurityTokenHandler, ..." gt; lt;samlSecurityTokenRequirement issuerCertificateRevocationMode="Online" issuerCertificateValidationMode="ChainTrust" / gt; lt;/add gt;IdentityModel
Thursday, 24 December 2009 08:38:32 UTC
Wednesday, 23 December 2009
WIF Configuration ndash; Part 2: SecurityTokenHandlerConfigurationThe workhorse of WIF are security token handler. Again token handler can be use independently of the WIF configuration system – or together. The “stand-alone” use caseYou can simply new up a token handler (e.g. the SAML 1.1 handler) in an arbitrary application. var saml11Handler = new Saml11SecurityTokenHandler(); But a token handler needs more information to do its work (issuer name registry, audience URIs, certificate validation etc.). This information is all encapsulated in the SecurityTokenHandlerConfiguration class. You can reach into that class from the token handler’s Configuration property. Configuration is null by default and must be newed up and set manually. Handler collectionsAnother option is to group a bunch of token handlers into a collection. This is useful when you have to deal with a number of in/output token types or need to chain token handlers (e.g. for encryption or compression). Collections also allow to share token handler configuration across contained handlers. When you new up a SecurityTokenHandlerCollection you have the choice of passing in a SecurityTokenHandlerConfiguration instance, or you use a default configuration (not sure if these values are documented – use reflector ;). When you add a handler to a collection, the collection checks if the handler already has some configuration set (by checking if Configuration is not null). If this is not the case, then handler inherits the collection configuration. var samlHandlers = new SecurityTokenHandlerCollection(new SecurityTokenHandler[] { saml11Handler, new Saml2SecurityTokenHandler() });?xml:namespace prefix = o / Another way to new up a handler collection is to use the static CreateDefaultSecurityTokenHandlerCollection method on the collection. This creates a collection with all default token handlers shipping with WIF. Again you have the option to pass in a configuration object. Using configurationToken handler configuration is typically an ideal candidate for configuration files. When you want to support that, you have two choices. Either copy the values from configuration, or use the configuration system to create and configure the handler. Copying from configuration can be handy sometimes. To do that use the approach shown in my previous post to load the service configuration manually. The WIF security token handler configuration section also has the concept of named handler collections. There is always a default token handler collection, but you can have additional ones – each with their own configuration, e.g.: lt;securityTokenHandlers gt; lt;!-- default token handlers - inherit global configuration settings -- gt; lt;securityTokenHandlerConfiguration gt; lt;!-- override with local configuration -- gt; lt;audienceUris gt; lt;add value="http://bar" / gt; lt;/audienceUris gt; lt;/securityTokenHandlerConfiguration gt; lt;/securityTokenHandlers gt; lt;securityTokenHandlers name="AccessToken" gt; lt;!-- named token handler collection - inherit global configuration settings -- gt; lt;securityTokenHandlerConfiguration gt; lt;!-- override with local configuration -- gt; lt;audienceUris mode="Always" gt; lt;add value="http://custom/*" / gt; lt;/audienceUris gt; lt;tokenReplayDetection enabled="true" / gt; lt;certificateValidation gt; lt;certificateValidator type="AccessCertValidation, ..."/ gt; lt;/certificateValidation gt; lt;/securityTokenHandlerConfiguration gt; lt;clear / gt; lt;add type="AccessSecurityTokenHandler, …" / gt; lt;add type="CompressedSecurityTokenHandler, …" / gt; lt;/securityTokenHandlers gt; Programmatically, you can get to the standard token handler collection using the SecurityTokenHandlers property on ServiceConfiguration. To get to the named token handlers, you use the SecurityTokenHandlerCollectionManager, e.g. like this: var accessHandlers = config.SecurityTokenHandlerCollectionManager["AccessToken"]; So as a rule of thumb: when you new up handlers or collections yourself, you are responsible for programmatic configuration. When you use ServiceConfiguration, the config file settings are applied automatically.IdentityModel
Wednesday, 23 December 2009 17:38:38 UTC
Tuesday, 22 December 2009
WIF Configuration ndash; Part 1: ServiceConfigurationWIF supports a flexible configuration system and various ways to programmatically interact with that configuration. This flexibility comes in two ways: Named configuration elements that you can selectively load (service amp; token handler configuration) Configuration extensibility (e.g. for token handlers, issuer name registries or claims authorization) In this first part I’ll focus on the service configuration. The WIF configuration can have several service elements. Services can be named, the unnamed element becomes the default configuration: lt;microsoft.identityModel gt; lt;service gt; lt;!-- default configuration -- gt; lt;/service gt; lt;service name="alternateConfiguration" gt; lt;!-- alternate configuration -- gt; lt;/service gt; lt;/microsoft.identityModel gt;?xml:namespace prefix = o / You can get a handle to the configuration by newing up a ServiceConfiguration object. The ctor allows to optionally pass in the name of the service. From there on you have an OM that represents the various configuration options. This is useful when you build your own integration, but for WCF and ASP.NET there is already an infrastructure in place. How to couple configuration with a relying partyBy default the standard hosting plumbing uses the default service configuration, but there are various ways to make this dynamic (e.g. for different environment like dev, staging etc). In ASP.NET you can subscribe to the ServiceConfigurationCreated event of the FederatedAuthentication class. This event gets fired during initialization and gives you the chance to load an arbitrary configuration and pass that back via the ServiceConfigurationCreatedEventArgs.You can then access the current configuration at any point via FederatedAuthentication.ServiceConfiguration (since creating a configuration is expensive, this class takes also care of caching). In WCF you wire up WIF with by calling FederatedServiceCredentials.ConfigureServiceHost(…). This call allows you to either pass in an instance of ServiceConfiguration or the stringified name of the service. Another option is to use the ConfigureServiceHostBehavior from configuration. Again this behavior has a parameter called serviceName. You can then access the current configuration either by finding the FederatedServiceCredentials behavior from the ServiceHost description (if you have access to the ServiceHost) obtain it from a MessageProperty called ServiceConfiguration. HTHASP.NET | IdentityModel | WCF
Tuesday, 22 December 2009 09:34:59 UTC
Thursday, 10 December 2009
Troopers10The annual Troopers conference takes place in my home town – Heidelberg – this year. nice ;) If you wanna know more about all things security wrt e.g. Blackberry, SSL/TLS, outsourcing, rootkits, botnets, SAP, cloud computing, you name it. This is the place to be. I will do a talk about the opportunities and risks of federated identity. See you there!Conferences
Thursday, 10 December 2009 07:49:52 UTC
Wednesday, 02 December 2009
Baier amp; Weyer on WIFWe had the pleasure to have a chat with Richard and Carl about what’s nearest and dearest to my heart – WIF ;) Enjoy…
Wednesday, 02 December 2009 20:21:15 UTC
Thursday, 26 November 2009
Thinktecture.IdentityModel v0.6This version is compiled against WIF RTM. Some stuff is still experimental. But feel free to play around ;)IdentityModel
Thursday, 26 November 2009 12:28:47 UTC
Wednesday, 18 November 2009
IDFX to Zermatt to Geneva hellip; to hellip; WIF RTM!It’s been a long way…. I love it!IdentityModel
Wednesday, 18 November 2009 08:02:15 UTC
Wednesday, 11 November 2009
StarterRP v0.95 (for WIF RC)Updated StarterRP to go with the 0.95 release of the StarterSTS. Changes include: added more SOAP endpoints to the WCF RP message, mixed mode, simple (for Silverlight clients) added a Silverlight client that can retrieve tokens and send them to RPs added OpenID bridge test to the ASP.NET RP Same disclaimer as here applies.IdentityModel
Wednesday, 11 November 2009 08:06:30 UTC
Tuesday, 10 November 2009
StarterSTS v0.95 (for WIF RC)I uploaded an interim release of the StarterSTS to codeplex. This release is not fully tested – and is mainly available to provide compatibility with WIF RC. There are some new features – and I hope I have not introduced any regression bugs. Please contact me via the codeplex forum when you have questions. Some new features: added a simple HTTP and SOAP based endpoint to request token added support to bridge OpenID logons to WS-Federation you can specify a separate signing key for bridged authentication, so RPs can distinguish between native and bridged authentication config changes to accomodate the various endpoints WS-Trust (message security) WS-Trust (mixed mode security) simple HTTP simple SOAP OpenID bridge WS-Federation metadata did some refactoring to allow easier pluggability and customizations retrieving certificates (CertificateProvider) retrieving claims (ClaimsProvider) analyzing an RST (PolicyOptions and PolicyScope) validating the request against configured policy (PolicyValidator) added optional confirmation screen after login when enabled, the user has to confirm before StarterSTS issues the token this is an additional countermeasure against one-click attacks Have fun.IdentityModel
Tuesday, 10 November 2009 18:07:02 UTC
Sunday, 08 November 2009
Thinktecture.IdentityModel updated for WIF RCdownload here.IdentityModel
Sunday, 08 November 2009 12:40:48 UTC
Wednesday, 28 October 2009
Using Silverlight to Access WIF secured WCF ServicesThis topic comes up quite often recently – so I hope the title is search engine friendly. Disclaimer: At the time of this writing, the current version of Silverlight is v3 and WIF is in beta 2. Hopefully this will be a non-issue soon. I talk a lot about claims, tokens and WIF/ADFS 2 to customers. All is good and fine and they like it. Another technology that comes up very often is Silverlight – and especially the “story” of Silverlight and WCF/WIF. Now this is not an easy question to answer. When thinking about Silverlight and back-end security in general – there are two fundamental scenarios – short of really good names – I call them “passive” and “active”. PassiveWith passive I mean, that the browser has already established a security context with the back-end system the Silverlight .XAP uses (and typically is also hosted at). An example would be that the user first authenticates with the web application and then starts the Silverlight app from there. In this case all the authentication related work was done by browser beforehand and all back-end requests simply re-transmit authentication headers, cookies and the like. This is not different with WIF secured ASP.NET applications. Eugenio has a good example of this here. This approach works fine while running in the browser and using “application-local” resources only. ActiveThis is the scenario I really want to talk about. In this case the .XAP comes from some server down to the client (in or out-of-browser) and wants to communicate with some back-end service on a different machine. This back-end service requires an issued token from a STS. Those of you with WCF background will say: “that’s what the federation bindings in WCF are for”. But there is no federation binding in Silverlight. If you need to enable such a scenario, you have to use several workarounds. Requesting a TokenSince Silverlight has no support for WS-Trust, we must find another way to request a token from a STS. Thanks to WIF this is not hard to do when you control the token service. You could add a simple REST or SOAP head that returns tokens. I wrote about this approach here. Some remarks here: Since you cannot do the proof of possession crypto in Silverlight, you need to request bearer tokens from the STS. The STS roundtrip is a cross-domain request. This means that the STS needs a client access policy (see here). You have to somehow authenticate with the STS. Silverlight has no support for Kerberos or client certificates. Basically you are stuck with some kind of userid/secret credential. I wrote about that here. Sending the token to the ServiceThis is the slightly more complicated part. Since Silverlight has no support for issued tokens, you have to manually embed the token in the outgoing SOAP security header. This is not as scary as it sounds. There is the so called Basic Security Profile in WS-Security which allows sending a simple security header with a timestamp and a token over SSL. This can be encapsulated in a MessageHeader derived class.public class SecurityMessageHeader : MessageHeader{ string _token; string _nsUtility = "..."; public SecurityMessageHeader(string token) { _token = token; } protected override void OnWriteHeaderContents( XmlDictionaryWriter writer, MessageVersion messageVersion) { DateTime now = DateTime.UtcNow; string created = XmlConvert.ToString( now, "yyyy-MM-ddTHH:mm:ss.fffZ"); string expires = XmlConvert.ToString( now.AddMinutes(5), "yyyy-MM-ddTHH:mm:ss.fffZ"); writer.WriteStartElement("Timestamp", _nsUtility); writer.WriteAttributeString("Id", _nsUtility, "_0"); writer.WriteElementString("Created", _nsUtility, created); writer.WriteElementString("Expires", _nsUtility, expires); writer.WriteEndElement(); writer.WriteNode(XmlReader.Create( new StringReader(_token)), false); } public override string Name { get { return "Security"; } } public override string Namespace { get { return "..."; } }} Afterwards you can attach the header to outgoing calls: var factory = new ChannelFactory lt;ServiceContract gt;("client");var proxy = factory.CreateChannel();using (var scope = new OperationContextScope(proxy as IContextChannel)){ OperationContext.Current.OutgoingMessageHeaders.Add( new SecurityMessageHeader(token)); proxy.BeginOperation(result = gt; { ... }, null);}?xml:namespace prefix = o / The binding on the client side is a binding with no client credential but SSL (the binary encoder is not required and used only for performance): lt;customBinding gt; lt;binding name="BearerTokensOverTransport" gt; lt;binaryMessageEncoding / gt; lt;httpsTransport / gt; lt;/binding gt; lt;/customBinding gt; On the service side, you need a binding that accepts bearer tokens over transport security, like this: lt;customBinding gt; lt;binding name="simple" gt; lt;security authenticationMode="IssuedTokenOverTransport" messageSecurityVersion="WSSecurity11 WSTrust13 WSSecureConversation13 WSSecurityPolicy12 BasicSecurityProfile10" gt; lt;issuedTokenParameters keyType="BearerKey" / gt; lt;/security gt; lt;binaryMessageEncoding / gt; lt;httpsTransport / gt; lt;/binding gt; lt;/customBinding gt; The rest works as normal. You have to enable WIF in the service and you get your IClaimsPrincipal. Some remarks: Again this service needs a client access policy for Silverlight cross domain calls. Keep in mind that these are bearer tokens. When you have a scenario that requires proof of possession, this will not work The SOAP response from the service will also contain a security header. Since the client is not configured for security this header may be unexpected. Silverlight does not seem to care, but other web service stacks might. In WCF you can work around that problem by adding the ValidateMustUnderstand behavior to the client stack. The complete code (STS extensions, Silverlight client and back-end service) is included in the next drop of the StarterSTS (version 0.95). I will upload that soon. HTHIdentityModel | WCF
Wednesday, 28 October 2009 08:04:00 UTC
Monday, 26 October 2009
Thinktecture.IdentityModelOver the last years I have worked with several incarnations of what is now called the Windows Identity Foundation (WIF). Throughout that time I continuously built a little helper library that made common tasks easier to accomplish. Now that WIF is near to its release, I put that library (now called Thinktecture.IdentityModel) on Codeplex. The library includes: Extension methods for IClaimsIdentity, IClaimsPrincipal, IPrincipal XmlElement, XElement, XmlReader RSA, GenericXmlSecurityToken Extensions to ClaimsAuthorizationManager (inspecting messages, custom principals) Logging extensions for SecurityTokenService Simple STS (e.g. for REST) Helpers for WS-Federation message handling (e.g. as a replacement for the STS WebControl) Sample security tokens and security token handlers simple access token with expiration compressed security token API and configuration section for easy certificate loading Diagnostics helpers ASP.NET WebControl for invoking an identity selector (e.g. CardSpace) I have also added some samples and a rudimentary API documentation. You can download the whole package Feel free to contact me via the forum when you have questions or found a bug.
Monday, 26 October 2009 17:01:47 UTC
Saturday, 17 October 2009
Guide to WCF ExtensibilityWCF extensibility is not trivial – this looks like it could become a very valuable source…WCF
Saturday, 17 October 2009 08:51:42 UTC
Thursday, 08 October 2009
StarterSTS, WIF, Identity on Channel9Dariusz interviewed me for Channel9. You can find the recording here. Have fun ;)IdentityModel
Thursday, 08 October 2009 11:15:46 UTC
Monday, 05 October 2009
Claims based Identity amp; Access Control Guide ndash; Early drafts availableEugenio just announced that the codeplex site is up now! Have a look at the draft documents – feedback is always welcome!!IdentityModel
Monday, 05 October 2009 05:47:39 UTC
Sunday, 13 September 2009
Restful Token Service Endpoints and Silverlight ClientsIt turns out that there is no way in Silverlight to send credentials using the standard HTTP Authorize header (see here). WTF?!. You have to use a custom HTTP header to transmit credentials in this case, e.g. X-Authorize (nice?). I have adjusted my service code to accept both headers and will update the StarterSTS bits on Codeplex.IdentityModel
Sunday, 13 September 2009 08:11:35 UTC
Friday, 11 September 2009
StarterSTS Version 0.93I just uploaded a minor update. refactored ScopeOptions to PolicyOptions and added a PolicyScope class CertificateProvider class abstracts physical loading of relying party encryption certificates /users/restIssue.svc is a Restful token issuance endpoint – you can use a simple GET to retrieve a token (see here) btw – this is the client code you can use to talk to the REST issuance endpoint: public static string GetToken( string username, string password, string uri, string realm){ using (var client = new WebClient()) { var encoding = Encoding.GetEncoding("iso-8859-1"); string encodedCreds = Convert.ToBase64String( encoding.GetBytes(String.Format("{0}:{1}", username, password))); string authHeader = string.Format("Basic {0}", encodedCreds); realm = HttpUtility.UrlEncode(realm); client.Headers.Add(HttpRequestHeader.Authorization, authHeader);?xml:namespace prefix = o / return client.DownloadString( string.Format("{0}/?realm={1}", uri, realm)); }}IdentityModel
Friday, 11 September 2009 17:43:51 UTC
Adding a REST Endpoint to a WIF Token ServiceSometimes it is useful to have a really simple way to acquire a token from a token service – without having to fiddle around with WS-Federation or WS-Trust. Issuing a simple GET request against a token issuance endpoint seems to fulfill that requirement. So I decided to a add a simple HTTP endpoint to my STS using the WCF web programming model: [ServiceContract]public interface IRestfulTokenServiceContract{ [OperationContract] [WebGet(UriTemplate = "/?realm={realm}")] XElement Issue(string realm);}?xml:namespace prefix = o / You could provide more parameters here (like token type, lifetime etc.) but i decided to keep it simple. For the implementation you have to decide which authentication types you want to support. Since I needed username/password authentication I used Cibrax’ excellent basic authentication extension. If you need to support client certificates, you would get the certificate details from WCF’s AuthorizationContext. To route the GET request to the existing token issuance logic, you can create the STS using the static CreateSecurityTokenService method on the SecurityTokenServiceConfiguration class. Then you have to construct a RST and IClaimsPrincipal to describe the token request and pass that into the Issue method. Afterwards you serialize the security token back as a HTTP response and you are done. I will incorporate that into the next drop of the StarterSTS – but for now here is the code:public class RestfulTokenService : IRestfulTokenServiceContract{ public XElement Issue(string realm) { EndpointAddress epRealm; try { epRealm = new EndpointAddress(realm); } catch { WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.BadRequest; return null; } RequestSecurityToken rst = new RequestSecurityToken { AppliesTo = epRealm, KeyType = KeyTypeConstants.Bearer }; var sts = new StarterTokenServiceConfiguration().CreateSecurityTokenService(); var rstr = sts.Issue(CreatePrincipal(), rst); StringBuilder sb = new StringBuilder(); var writer = XmlWriter.Create(sb); var col =SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(); col.WriteSecurityToken(writer, rstr.RequestedSecurityToken.SecurityToken); writer.Flush(); WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"; return XElement.Parse(sb.ToString()); } private IClaimsPrincipal CreatePrincipal() { if (Thread.CurrentPrincipal == null || Thread.CurrentPrincipal.Identity == null || string.IsNullOrEmpty(Thread.CurrentPrincipal.Identity.Name)) { throw new InvalidRequestException("unknown client"); } var identity = new ClaimsIdentity( new Claim(WSIdentityConstants.ClaimTypes.Name, Thread.CurrentPrincipal.Identity.Name)); return new ClaimsPrincipal(identity); }IdentityModel
Friday, 11 September 2009 09:51:13 UTC
Tuesday, 01 September 2009
StarterSTS Version 0.92I have an update to the StarterSTS up on codeplex. There is also a new screencast that details the changes from the last version. Have fun!IdentityModel
Tuesday, 01 September 2009 10:32:50 UTC
Friday, 28 August 2009
.NET Usergroup Frankfurt ndash; WIF, ADFS 2, CardSpace 2Am 15. September sind Christian und Ich in Frankfurt und plaudern mal nen Abend lang über unsere Erfahrungen mit Identity und Claims in verteilten Anwendungen. Wir freuen uns schon und das sollte ein netter Abend werden. Es sind noch Plätze frei – Anmeldung ist hier erforderlich. Vielleicht sieht man sich ja dort.Conferences | IdentityModel
Friday, 28 August 2009 18:48:03 UTC
Monday, 24 August 2009
Patterns amp; Practices - Claims based Authentication amp; Authorization GuideSummer break is over – and exciting times lie ahead. Over the course of the next months I will be working with Eugenio, Keith, Vittorio, Matias and David. The end result will (hopefully) be a very interesting, useful and pragmatic guide to all things claims. Eugenio already posted some details on the guide and we will be releasing interim version so you can give us feedback. Watch this space!IdentityModel
Monday, 24 August 2009 06:11:21 UTC
Thursday, 30 July 2009
WCF Source Code for Download
Thursday, 30 July 2009 05:17:55 UTC
Wednesday, 22 July 2009
Claims Authorization in WIF Beta 2 ndash; ASP.NET and WCF IntegrationIn the previous post I illustrated how the basic claims authorization infrastructure in WIF (formerly Geneva) works. In this post I want to focus more on how claims authorization behaves when integrated in WCF and ASP.NET. ASP.NETIn addition to using the claims authorization manager manually like I showed you in the last post, you can also opt-in to per-request claims authorization (think of it as a replacement for the “classic” URL authorization module in ASP.NET / IIS). For this purpose you’ll find an HTTP module called ClaimsAuthorizationModule in the Microsoft.IdentityModel.Web namespace. This module simply subscribes to the AuthorizeRequest processing stage and calls the configured claims authorization manager for every request. The AuthorizationContext that gets passed in the manager consists of the current IClaimsPrincipal, the request URL and the HTTP method. If you want to do tricks like custom IClaimsPrincipal implementations, you’d either exchange the principal before you hit the claims authorization manager (in PostAuthenticateRequest) or after it (in PostAuthorizeRequest). WCFAs usual things are a little more complex in WCF. Authorization (amongst other things) is driven by a ServiceAuthorizationManager in WCF. When you call ConfigureServiceHost, WIF puts a special version of that class, the IdentityModelServiceAuthorizationManager, in place. This class in turn calls out to the configured ClaimsAuthorizationManager. In that case the WS-Addressing To and the Action header are passed in for every request. HTHWCF | ASP.NET | IdentityModel
Wednesday, 22 July 2009 05:24:30 UTC
Friday, 10 July 2009
Claims Authorization in Geneva Beta 2 - IntroductionI guess you already heard the term “claims based authorization” several times by now. But how exactly does the authorization work? The typical pattern is that you iterate through the claims associated with the user and search for a special claim and maybe also a special value of that claim. Based on that you can grant/deny access or modify behavior or UI elements. This typically leads to code like this: if (principal.ClaimExists("http://someclaim", "somevalue")) {} or principal.DemandClaim(WSAuthorizationConstants.Action, "AddCustomer");?xml:namespace prefix = o / This has the downside, that claim types and values are embedded in your application code and this may become hard to maintain in certain situations. That’s the reason why the Geneva framework Beta 2 introduced a built-in infrastructure for authorization that operates at a higher level of abstraction. In Geneva authorization information is abstracted as a resource that the subject tries to access and the action the subject wants to perform on that resource. The container for this information is called the AuthorizationContext. Operation and action are collections of claims. This allows to express from simple to more complicated authorization statements. A simple resource/action pair could be e.g. Directory/Browse. A more complicated statement could be e.g. “Purge printer queue of laser printer in building 61”. That’s how you could construct the corresponding AuthorizationContext: var simpleContext = new AuthorizationContext(principal, "Directory", "Browse"); and var advContext = new AuthorizationContext(principal, new Collection lt;Claim gt; { new Claim("http://claims/device", "Printer"), new Claim("http://claims/building", "61") }, new Collection lt;Claim gt; { new Claim(WSAuthorizationConstants.Action, "PurgeQueue") }); The second piece of plumbing introduced by Geneva is the ClaimsAuthorizationManager. You derive from this class and implement the CheckAccess method. This method accepts an AuthorizationContext and returns true/false. In this method you have to do whatever mapping is necessary to resolve the resource/action pair to claims of the subject. Use this sample authorization manager to inspect the data that gets passed in: class SimpleAuthorizationManager : ClaimsAuthorizationManager{ public override bool CheckAccess(AuthorizationContext context) { Console.WriteLine("SimpleAuthorizationManager:"); Console.WriteLine("\nSubject: {0}\n", context.Subject.Identity.Name); Console.WriteLine("Actions:"); foreach (var action in context.Action) { Console.WriteLine(" {0}", action.ClaimType); Console.WriteLine(" {0}\n", action.Value); } Console.WriteLine("Resources:"); foreach (var resource in context.Resource) { Console.WriteLine(" {0}", resource.ClaimType); Console.WriteLine(" {0}\n", resource.Value); } return true; }} While you could manually new up that class and directly call CheckAccess method – you can also use configuration to create the authorization manager. This has some interesting features. First you need to configure the authorization manager in config: lt;microsoft.identityModel gt; lt;service gt; lt;claimsAuthorizationManagertype="LeastPrivilege.PolicyAuthorizationManager, ClaimsAuthorization" / gt; lt;/service gt; lt;/microsoft.identityModel gt; And then use the following code to create and use the authorization manager: var config = new ServiceConfiguration();var authz = config.ClaimsAuthorizationManager;var simpleContext = new AuthorizationContext( principal, "Directory", "Browse");var allowed = authz.CheckAccess(simpleContext); You can also use the ClaimsPrincipalPermission/Attribute classes which simplify the call and automate the creation from configuration: new ClaimsPrincipalPermission("Directory", "Browse").Demand(); or [ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Directory", Operation = "Browse")]private static void BrowseDirectory(){ } As with the normal PrincipalPermission – these classes throw a SecurityException and assume that you have populated Thread.CurrentPrincipal. The configuration for the claims authorization manager has an interesting extensibility point. You can attach arbitrary XML to the configuration element. This allows to create policy statements directly in config or provide enough information for the authorization manager to load the policy from somewhere else. Whenever such an attached XML fragment exists, the configuration loader calls a special constructor of ClaimsAuthorizationManager and passes over the fragment as an XmlNodeList. public class PolicyAuthorizationManager : ClaimsAuthorizationManager{ // this ctor gets called when there is a child element in app.config public PolicyAuthorizationManager( object objXmlElement ) { XmlNodeList nodes = objXmlElement as XmlNodeList; Process(nodes); }} The same mechanism is also used for SecurityTokenHandlers btw. The Geneva SDK includes a sample that shows how to use this extensibility point to parse authorization policy (in the Extensibility folder). With this sample you could write something like this for the above authorization statements: lt;claimsAuthorizationManager type="type" gt; lt;policy resource="Directory" action="Browse" gt; lt;claim claimType="" claimValue="Users" / gt; lt;/policy gt; lt;policy resource="Printer_61" action="PurgeQueue" gt; lt;or gt; lt;claim claimType="" claimValue="Enterprise Administrators" / gt; lt;and gt; lt;claim claimType="" claimValue="Administrators" / gt; lt;claim claimType=http://claims/building claimValue="61" / gt; lt;/and gt; lt;/or gt; lt;/policy gt; lt;/claimsAuthorizationManager gt; Everything you’ve seen here can be used in arbitrary application types. In the next post I show how this is integrated with WCF and ASP.NET.
Friday, 10 July 2009 14:29:17 UTC
Defeating SSLNot a really new paper – but definitely recommended reading. Some lessons learned: Moxie is not really attacking SSL – but uses HTTP to bypass HTTPS. Switch to SSL as early as possible – but that might be too late already. Users never type https:// (nor http://) – they start with plain text and hope the application is doing the right thing. Fortunately (web) services are not affected. There is no human doing the http vs https decision. WCF e.g. also doesn’t like to be downgraded to plain text whenever credentials are involved. That’s a good thing in the face of such attacks. Endpoint Identities (an addition to WS-Addressing) are a good thing. I see interesting times for passive profile SSO scenarios like WS-Federation. This doesn’t mean that these technologies open new holes – it is just that the (username/password) credentials we send around are much more powerful because they can be used in multiple applications. This also means – if you are building a passive STS – you should not solely rely on SSL to secure your tokens. Encrypt them!IdentityModel | ASP.NET | WCF
Friday, 10 July 2009 10:09:50 UTC
Friday, 03 July 2009
A closer look at Sandboxing in (ASP.NET) V4In the last two posts I described how ASP.NET uses the homogenous AppDomain model to implement partially trusted apps. In ASP.NET you use the combination of a trust level (aka grant set) and a list of full trust assemblies to setup the homogenous AppDomain. This maps directly to the AppDomain.Create() call that allows the corresponding parameters to be passed in. Another option is to determine the trust level of application assemblies using a policy resolver. The resolver gets called when an assembly gets loaded into the AppDomain and you can dynamically specify if the assembly should run in full trust or the AppDomain grant set. The second option is implemented using the new features around AppDomain managers in .NET 4.0 (read more here, here, here). These new features basically boil down to two new ways to specify an AppDomainManager for the default or newly created AppDomains. You can now either use configuration (in the runtime section) or specify the AppDomainManager type on the AppDomainSetup object when manually creating AppDomains. This is exactly what ASP.NET is doing. The AppDomainManager implemented in System.Web.Hosting.ApplicationManager+AspNetAppDomainManager is used for ASP.NET created AppDomains. This manager in turn uses a custom HostSecurityManager (implemented in System.Web.Hosting.ApplicationManager+AspNetHostSecurityManager). This host security manager in in turn expresses his interest to resolve policy when assemblies get loaded (using the Flags property). In the ResolvePolicy method, the host security manager calls out to the policy resolver (if specified). The return is then parsed and turned into either full trust/appdomain trust/nothing permission sets. Nice. This mechanism is not special to ASP.NET – and can be used in arbitrary applications. Useful for writing hosts with more advanced requirements. (thanks to shawnfa/stefsch)FX Security | ASP.NET
Friday, 03 July 2009 09:37:41 UTC
Thursday, 02 July 2009
Identity Metasystem Interoperability Version 1.0The IMI spec is now approved. Grats! Read more here and get the spec here.IdentityModel
Thursday, 02 July 2009 07:25:29 UTC
Wednesday, 01 July 2009
Partial Trust ASP.NET in 4.0 (Advanced Scenarios)In the last post I showed you how to use the new CLR security model to do sandboxing in ASP.NET. One new hook into this system is a custom host security policy resolver. A policy resolver is a class that derives from System.Web.Hosting.HostSecurityPolicyResolver. The idea behind this extensibility point is, that a resolver can decide at runtime (as opposed to the static fullTrustAssemblies configuration element) in which “permission bucket” the assembly should get loaded – AppDomain grant set, full trust or nothing. A resolver has a single method called ResolvePolicy. ASP.NET hands in the evidence of every application assembly that gets loaded into the resolver, and it is the implementer’s job to decide the “trust level”. ResolvePolicy returns a HostSecurityPolicyResults enum which can have one of these values: DefaultPolicy, FullTrust, AppDomainTrust or Nothing. You register the resolver using the following config element: lt;trust level="Medium" permissionSetName="ASP.Net" hostSecurityPolicyResolverType="Policy.PolicyResolver, …" / gt;?xml:namespace prefix = o / A resolver must be in the GAC – otherwise you may receive a strange exception saying “assembly still being loaded”… HTHFX Security | ASP.NET
Wednesday, 01 July 2009 06:40:07 UTC
Tuesday, 30 June 2009
Partial Trust ASP.NET in 4.0In .NET v4 there are substantial changes to the CLR security model. Read about all the details here. With Beta 1 in hand I gave the new model a try in the probably most popular host for partial trust – ASP.NET.
You start with setting the trust level in web.config. This works exactly the same as in pre-V4. Also the same web_xytrust.config files from the framework configuration directory are used. Since policy levels and code groups are not in effect any longer in V4, ASP.NET by default uses the named permission set called ASP.Net as the grant set for the AppDomain. You can also specify a different set via the new permissionSetName attribute.
lt;trust level="Medium" permissionSetName="ASP.Net" / gt;?xml:namespace prefix = o /
So far everything behaves like in CLR2. Now a typical thing to do would be to factor out the “dangerous” code into separate assemblies and grant these assemblies full trust to do their work. In CLR2 you either GACed such an assembly or modified the security policy to grant whatever permissions were needed.
Since there is no security policy anymore in V4 and ASP.NET has moved to the homogenous AppDomain model – things work differently (and easier) now. In a homogenous AppDomain there are permission-wise two types of assemblies – ones constrained by the AppDomain grant set and full trust assemblies. With the new fullTrustAssemblies configuration element, you can specify which assemblies should be loaded in full trust, e.g.:
lt;fullTrustAssemblies gt; lt;add assemblyName="HelperLib" version="" publicKey="0024…cb0" / gt; lt;/fullTrustAssemblies gt;
To make HelperLib callable from partial trust, you have to add the standard [AllowPartiallyTrustedCallers] attribute to the assembly. With the new transparency model in V4, APTCA means that the library provides services to partially trusted code and can contain critical and safe critical code. All un-annotated code in an APTCA assembly becomes security transparent by default.
This is a huge improvement over the old model. Since partially trusted code is always transparent, it can only call transparent or safe critical code. The typical pattern is that you provide safe critical “gateways” in your library where you do all the security checks, input validation and asserts (if necessary). From there you then call into the critical code (e.g. a library function).
The following is a simple example of a library that provides read access to certain directories to partially trusted ASP.NET applications:
[assembly: AllowPartiallyTrustedCallers]namespace HelperLib{ public class Helper { [SecuritySafeCritical] public string ReadFile(string filename) { var perm = new FileIOPermission( FileIOPermissionAccess.Read, GetAllowedContentDirs()); perm.Assert(); return File.ReadAllText(filename); } }}
HTHASP.NET | FX Security
Tuesday, 30 June 2009 12:02:08 UTC
Wednesday, 17 June 2009
Updated Starter STSI just uploaded a minor update to the Starter STS sample to codeplex. This release adds more options for realm checking (see the allowKnownRealmsOnly config switch) as well as Information Card issuance. As always – feedback is welcome! http://startersts.codeplex.comIdentityModel | ASP.NET | WCF
Wednesday, 17 June 2009 07:21:52 UTC
Friday, 05 June 2009
.NET Access Control Service Talk from Troopers09I did a talk about the ACS in May. It was interesting to present that topic to a non-Developer, non-Microsoft minded audience. Here’s the outcome: _IdentityModel
Friday, 05 June 2009 03:45:53 UTC
Thursday, 04 June 2009
Writing Custom Attribute Stores for Geneva Server (B2)This document appeard on the connect site. Interesting. _IdentityModel
Thursday, 04 June 2009 06:31:37 UTC
Wednesday, 03 June 2009
Worker Process Accounts in IIS 7.5Windows 7 and Windows Server 2008 R2 ship with IIS 7.5. While migrating the StarterSTS, I made an interesting observation. I remember vaguely I read about that somewhere – but basically I got this error message: Cannot open database "aspnetdb" requested by the login. The login failed.Login failed for user 'IIS APPPOOL\DefaultAppPool'. That’s an interesting account. A closer look reveals, that in IIS manager you now have five accounts to choose from when setting up an App Pool: System, Network Service, Local Service, Custom… and ApplicationPoolIdentity. The default value is ApplicationPoolIdentity. With this new setting, a new primary SID is injected into the worker process – all Windows security checks are done against this new SID. Converting that NT Account to an SID reveals an S-1-5-82 – which was new to me. So in the light of the recent problems with system account sharing (here and here), this is a good change and makes it even easier to isolate worker processes. HTH IIS
Wednesday, 03 June 2009 18:59:03 UTC
Thursday, 28 May 2009
Geneva Framework Quick Tip: How to access ConfigurationRemember that Geneva framework is a framework – all the nice integration into WCF and ASP.NET is built on top of a public API. This also means that you can use Geneva framework for integration in arbitrary hosts and environments. One thing you most often need is access to the Geneva framework configuration (microsoft.identityModel section) from code – and again this is very easy:ServiceConfiguration config = new ServiceConfiguration(ServiceConfiguration.DefaultServiceName); HTHIdentityModel
Thursday, 28 May 2009 05:21:31 UTC
copy; Copyright 2011 Dominick Baier
|| | Page rendered at Friday, 04 March 2011 09:18:30 UTC




桌面软件: MyIP网站信息状态条  WebShot网页快照  SiteMapMaker网站地图生成 
网站信息: Alexa排名查询  PageRank查询/真假PR鉴别/PR劫持检测  外链检查  搜索引擎收录  搜索引擎反向链接  域名注册查询 
网页编辑: 颜色代码选择器  Html特殊符号 
网站调试: 蜘蛛抓取模拟  网站Header信息  网页源代码查看 
代码转换: 火星文查询  繁体/简体转换  Html/js代码转换  Html/UBB代码转换 
友情连接: CodeForge免费源码 PCFans IT资讯 Ngnix Lighttpd GPhone中国    更多... (PR<5自动转内页)
网站地图: 1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 250 300 350 400 450 500
免责声明 | 联系我们 | 交换友情链接 | 广告位招商QQ: 1967659002
© 2009 Dev by MYIP Elapsed:117.451ms 黑ICP备09072263号