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.

About these ads

One Response to “WPF Browser Hosted Applications (XBap) APTCA/Friend Assembly”

  1. Dalia Says:

    I need more info about how to create CLR to full trust xbap, I want to connect to sql server.

    thanks


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: