WPF Browser Hosted Applications (XBap) APTCA/Friend Assembly

Avalon browser hosted applications get trust based on the zone from which they deploy. This means Xbaps coming from Internet zone get Internet zone permission only and ones from Intranet zone get Intranet zone permissions etc…

These applications don’t have support for permission elevation where user can choose to give higher privileges than ones that application can get based on zone of deployment. There are three ways applications can demand more trust  that default permissionset allowed for the zone of deployment and demand can get satisfied.

  1. Deploy a custom CLR Security policy that modifies the default permissionset for the given zone
  2. Use a trusted publisher mechanism
  3. Use a fully trusted GAC‘ed assembly which allows partially trusted callers.

First way, is the most intrusive in terms of its impact. Only place it could be done is company intranet which is guaranteed to be secure. This means all the applications from anybody from that particular zone will get modified permission set. This can’t really work for Internet zone application because you would not deploy a custom CLR security policy on your machine that allows more trust to all the applications in the world.

Second way, is less intrusive than first one but it is still more open than the third one. By trusted publisher mechanism, you essentially say that all applications signed with that cert (which means all applications from particular publisher) can get permission set that they demand irrespective of their zone. This is still open check from end user’s perspective. because once this is granted anything from that publisher will run without a prompt. User needs to run full trust code (installer) on the machine to be able to do this.

Third way, can be less intrusive where installer runs to install a full trust assembly in the GAC which allows partially trusted callers. This in itself can be seen as worse than second option because GAC‘ed assembly that allows partially trusted caller means any code on Internet can call into that assembly. The security bar for this kind of assembly would/should be very high and it would mean you will need to think about not only bad used of your application calling that code but also *any* application calling that code. But you could lock down the code in this third way in such a way so that only your application and nobody else. It involves use of concept of Friend Assembly.  

For this to work three things need to happen…

  1. Assembly needs to be in the GAC to be found by Partially Trusted Code
  2. Assembly needs to to have AllowPartiallyTrustedCallers (assembly level) attribute so that it can be called by Partially Trusted Code
  3. Assembly needs to be marked InternalsVisibleTo (Assembly level) attribute so that it can be ONLY called by your Partially Trusted Code.

Doing first part, is pretty straightforward because on dev machine it can be done by GACUTIL or on user’s machine it can be done by installer.

Second part involves putting a assembly level attribute. You could put this in AssemblyInfo.cs that VS generates. It looks something like this…

//allows partially trusted caller
[assembly: System.Security.AllowPartiallyTrustedCallers]

Third part involves some more steps…

To use the InternalsVisibleTo in such a way that only your assembly can call into it, caller assembly needs to be strongly name signed. So lets say you will use FriendCaller.snk file that you can generate using sn.exe tool. You will use Public Key of that key to specific InternalsVisibleTo attribute. So it looks something like this…

//uses the strongname of the assembly to make internals visible
[assembly: InternalsVisibleTo("FriendCaller,PublicKey=002400000480000094000000060200000024000
05253413100040000010001008b486e36a11b892dbe3c19af141bd9123c696
2ef7945fe10b1131e5bf6852d4a31ae192c21ad65ebe054fa94c6ac19c0c6ecd85
261ee2b0e7e4029aa8f569eddce5310c8731c8976405d19877c18163c6b0199
ffc4c617f8ab095b2b750dcf204e65bc000818ce36ce46e5c3f4d8a7ddfe6f9dfc3
99b65df1281a52a2ae5accc")]

Note: I put line breaks to make it readable. In real code it would be one big line unless you have wrap set.

 First part of the attribute is pretty straight forward, it is the name of your assembly without the extension (.dll or .exe etc).

Here is how you generate second part…

  • sn -k FriendCaller.snk // Generate strong name key
  • sn -p FriendCaller.snk key.publickey // Extract public key from key.snk into key.publickey
  • sn -tp key.publickey > test.txt // dump the public key to text file instead of screen.
  • Copy paste in the public Key = part of the code above

Apart from these attributes the only code that I had in my sample FriendsCallee.dll is

using System;

namespace FriendCallee
{
        class MyPrivateClass
       {
                internal string PrivateFriendlyCall()
               {
                      return (“My friend is calling me”);
                }
        }
}

so all the classese and methods in my assembly are internal so nobody else could call into it from outside. As part of the post build process I added Gacutil command so that it gets added to GAC on my machine automatically. On users machine it would be installer doing it. Since you need to put this assembly in the GAC, it also needs to be strongly named signed but since it is irrelevant here, I am skipping that part.

Here is what I did to create an application…

  1. Create an XBAP from Visual Studio Template.(Assembly name FriendCaller.exe)
  2.  I will add reference to GAC’ed dll
  3. I will use the FriendCaller.snk to sign the assembly from Project/Properties Signing Tab.

Page1.xaml  of my applications looks like this…

<Page x:Class=”FriendCaller.Page1″
xmlns=”
http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”Page1″ Loaded=”OnPageLoaded”>
       <Grid>
               <TextBlock Name=”lblMessage”></TextBlock>
       </Grid>
</Page>

Page.xaml.cs looks like this…

namespace FriendCaller
{
          public partial class Page1 : System.Windows.Controls.Page
         {

                 public Page1()
                 {
                         InitializeComponent();
                  }

                 void OnPageLoaded(object sender, RoutedEventArgs e)
                  {
                            FriendCallee.MyPrivateClass mp = new FriendCallee.MyPrivateClass(); 
                            this.lblMessage.Text = mp.PrivateFriendlyCall();
                    }
          }
}

When you compile this application, I would have expected it to run and be able to call into a GAC’ed APTCA marked DLL even though I am calling internal method because FriendCaller.exe is friends with FriendsCallee.dll.

Unfortunately it did not work. CLR still threw security exception. For some reason, I needed to mark my application EXE (FriendCaller.exe) which was calling into that assembly also APTCA.

So when I added following code to AssemblyInfo.cs of my XBAP, it worked well as expected.

//allows partially trusted caller
[assembly: System.Security.AllowPartiallyTrustedCallers]

I have not yet figured out why I needed to add it or if there is better way to do this but once I do, I will post it.

Till then…you have a work around.

A Peace to End All Peace

I just started reading A Peace to End All Peace: The Fall of the Ottoman Empire and the Creation of the Modern Middle East. I have heard lot about this book so far. I have barely read Introudction but I am totally excited about reading this book. Title is based on a quote from Field Marshall Archibald Wavell that says

“After the ‘war to end war’ they seem to have been pretty successful in Paris at making a ‘Peace to end Peace.’ “

I found one good post with some perspective on Procrastination blog

RSS

I read this RSS releated post today on  Dead 2.0 blog. I must say this is one of my favorite technology blog. It was great to re-confirm how far away we (people who work in software) with people in real world who are supposed to use the tecnology. I loved the way Dead2.0 used term “Vanish” in context of RSS and his explaination. I remember reading one of the design books where books took power steering as one of the best designs because user never notices it working for it explicitly. RSS needs to be like that. I love RSS.

It is interesting from the perspective of usage pattern for the task. Before RSS, the only way I can read content is I have to visit individual sites. RSS solves the problems where I can read the feeds by getting updates etc but now user has to sacrifice the experiences that web site provide. I think what we need to do here so people get advantage of RSS without losing benefits of great experience.

 Here are few things I was thinking about ….

App Integration with RSS Reading experience

Today RSS feed reader has some standard UI that allows users to read it. But there is nothing content publisher can do to make that experience better.  We could solve this  Ability for RSS feed to say what their preferred reader is. This might be just a custom tag in RSS that specifies link to the reader. Link can point user to get richer application. User goes and installs the reader if they want it. 

Problem it solves…

  • User does not have to be stuck with what default UI and can get richer experience if they wanted

Problem it does not solve…

  • It is not integrated experience.
  •  User still has to go out of his way first time to get the reader. 
  • Different application can build different usage semantic and will be confusing for users. 

It would be great if there was an ability to RSS feed to specify the app they want to use for reading. That app gets executed when browser hits that RSS feed. This could also be done via Add-in model where browser provides the default viwer application and content provider provides addin that enhances that experience. This way browser can keep control over the usage sementic and keep it in the same ballpark. It means we only have platform for DATA part of the RSS but maybe we should have plugin based platform for RSS applications that closely integrated with browsers.

Got to figure out Way to Monetize RSS feeds.

I could think of 3 ways to let content publisher make money

Ads

  • Showing the ads RSS has as they are
  • Controlling the Ad experience in default RSS reader (special tag for Ads that get displayed on the side of the page etc)
  • We could also think of ways to get LIVE search ads in the news reader based on the content (This wont work for the people who make money off their own ads but might be interesting for free content)

Subscription (Authentication)

 There might be people who make money off of the subscription based content. That means they need to identify who the owner is no matter what the reading model is. This means we have to support authentication of this content and possibility obfuscation.

 Licensing: Viwer App having to licensed

I can see people actually making money off of partner deals such as Newyork times recommends “Foo” reader build by BAR company. They push people to use FOO through their  RSS and they 10% of every new license that comes because of nytimes feed. This might be weak.