Tag Archive for 'xbap'

XBAP Contest! Deadline: March 12, 2007

Josh Smith (formerly of Infragistics) is putting on an XBAP contest!

Submissions are required by March 12th.

I can’t wait to see what people create!

British Library – 3D Rare Books Experience as an XBAP

As Tim Sneath announced earlier in his blog today, the British Library has released a just awesome XBAP

I’ve been giddy about this app since I saw the first prototype.  Here’s an example of technology really opening doors and offering new experiences.  The public can see these Da Vinci’s notebooks, Mozart’s compositions, and many other (usually locked up) rare books in a fuller fidelity, richer environment than ever before.

Tim goes in to all the specific coolness of the app in his post.  I definitely recommend the read.

Try out ”Turning the Pages” here.

 

TOTALLY TOTALLY cool xbap: Doninoken

Hats off to the Japanese design agency Bascule for this excellent xbap.  The funky 3D & music is just awesome.  A great watch.

 

Notice the little camera in the lower left hand corner? Click on it to control the camera position and zoom in/out. Sweetness.

 

Thanks Karsten for the tip!

XBAP & Trust Levels

XAML Browser Applications (XBAPs) in this version are promptless in-browser experiences

This has many implications:

  1. clean experience when navigating to an XBAP.  (There is no Information Bar or security warning before launching the app.) 
  2. cached (not installed) on the user’s machine.
  3. security sandbox.

 

Sandboxed Applications

The third bullet above is especially important for XBAP developers.   XBAPs obey the security contract of being in the browser: they are sandboxed according to their deployment zone.  Today, there is no way to seamlessly “elevate” and prompt the user for additional permissions.  (This is an often-requested feature and something we are investigating for future versions.)  The sandboxed restriction also means that XBAP developers need to be conscious of the bounds of the security sandbox as they develop their app.  (See previous post.)

Note: By default, all XBAPs request the Internet Zone permission set in their application manifest.  In V1, there is no significant difference between the Internet & Intranet permission sets.

 

“I want my XBAP to run with full trust.  I heard there are workarounds..?”

Given the sandbox restrictions and the wide range of experiences desired in the browser, this is not surprisingly a frequently asked question about XBAPs. 

If you want full trust, you should first consider building a standalone installed WPF application.  These by default run in full trust and can be deployed using ClickOnce, giving many of the deployment benefits of a browser application.

If your scenario requires that you’re an XBAP, there is no built-in way for XBAPs to prompt and request more permissions. That being said, XBAPs are ClickOnce applications behind the scenes.  That means it is possible to use ClickOnce-based methods to gain access to trusted actions.  There are two main options:

  1. Install an AllowPartiallyTrustedCallersAttribute’d (APTCA)assembly in to the client’s Global Assembly Cache (GAC).  Use this full trust assembly to proxy calls for the XBAP.
  2. Install a certificate in to the user’s trusted publisher’s store.  Use ClickOnce trusted application deployment by signing the XBAP with the certificate.

Neither of these workarounds are ideal from a security standpoint, but we believe the latter is the better option.

GAC’d APTCA assemblies are accessible to ALL partial trust callers and therefore are susceptible to repurposing by 3rd parties.  There are ways to mitigate this exposure – for instance, one could use the [InternalsVisibleTo] attribute to only expose methods to specific “friend” XBAP assemblies.  However, mistakes or incomplete usage of this mitigation could potentially open wide security holes.  In addition, the management of installed APTCA assemblies is very end-user unfriendly.

For intranet XBAPs, pushing out a trusted publisher certificate through group policy is a fine way of enabling LOB scenarios. 

However, for consumer scenarios, trusted deployment via trusted publisher certs has its drawbacks.  This is because it affects more than just XBAP deployment:  many trust decisions prompts are bypassed for trusted publishers.  Still, this workaround has the advantage of being scoped to the specific publisher.

For V1 consumer XBAPs, we make the following recommendations:

  1. Be sure your app needs to be an XBAP.  (Can it be a full trust standalone ClickOnce application?)
  2. Trusted app deployment is preferred of the two workarounds.
  3. Use a separate cert to sign each XBAP group.  Otherwise, a user who decides to trust one set of XBAP will implicitly agree to trust all XBAPs (& ActiveX controls, etc) signed with that certificate.  This scopes the security impact (and responsibility) of any particular certificate.
  4. Use an MSI to install the cert.  This ensures installation is consistent with the configured security installation settings on the client machine (e.g. requiring Admin rights).
  5. Install the cert into the user’s trusted publisher store, not the machine’s.  This reduces the machine decisions that the trusted publisher cert can impact.
  6. Clearly notify the user at installation that they are changing the user’s trusted publisher store. 
  7. Provide clear installation instructions on the page containing the XBAP.  If the cert is not installed and the XBAP requests full trust, a “Trust Not Granted” error is shown.

Please use the above method with extreme care. We’re exploring changing XBAP elevation to work better in future versions.  Your feedback in this area, as always, is appreciated.

 

Other FAQs

How did you implement the sandbox?

The XBAP sandbox is based on the .NET Framework security model: Code Access Security.  In this model, permissions gate the actions that a particular app can do (i.e.  FileIOPermission controls file system access).  What permissions are granted depends on what deployment zone an application is deployed from.  A detailed explanation on our implementation strategy can be found in the WPF Sandbox Whitepaper.

When will you be expanding the sandbox?

We’ve had a lot of requests for specific features to be brought in to the Internet sandbox.  Currently, we’re exploring plans for our next version.  We would love feedback if there is a non-sandboxed feature that is blocking you.  Please leave comments on this blog post or send requests to wpfsec at microsoft dot com.

WPF Internet Sandbox Feature List (XBAPS & Loose XAML)

Two main types of WPF content is sandboxed today:

  • XAML Browser Applications (XBAPs).  XBAPs are online-only ClickOnce applications that are cached & run in the browser.
  • Loose XAML.  Loose XAML are XAML-only files that can be navigated to in the browser.

I’ve gotten questions about the specific feature list for the WPF sandbox.  Below is the high level list.   Other great resources about the sandbox include:

If you’re interested in why something was including/excluding from the sandbox, check the above whitepaper.  If you can’t find an answer here, feel free to post a comment on this blog entry.

V1 Internet Sandbox Features

These features are available in the WPF Internet sandbox:

Category

Features

General

Browser Window
Site of Origin (SOO) Access
IsolatedStorage (512KB Limit)
UIAutomation Providers
Commanding
Input Method Editors (IMEs)
Tablet Stylus/Ink
Simulated drag/drop via MouseCapture/MouseMove
OpenFileDialog
XAML Deserialization (via XamlWriter.Load)

Web Integration

Browser Download Dialog
TopLevel User-Initiated Navigation
mailto:links
URI Parameters
ASMX Web Services
HTTPWebRequest to Site of origin
XBAP/Loose XAML Hosted in IFRAME
Hosting of Site of Origin HTML pages

Visuals

2D/3D
Animations
Media (Site of Origin & Cross Domain)
Imaging/Audio/Video

Reading

FlowDocuments
XPS Documents
Embedded & System Fonts
CFF & TrueType Fonts

Editing

Spell Check
RichTextBox
Plaintext/Ink Clipboard Support
Partial XAML Clipboard Support
User Initiated Paste
Copy of Selected Content

Controls

All basic controls
Popups bound to Window

 

V1 Features Excluded from Internet Sandbox

The features are disabled in the WPF Internet sandbox.  Some these features were excluded from the sandbox for inherent security reasons.  Others were the result of V1 timeline/resource constraints. 

Category

Features

General

Window class (includes app-defined dialogs)
Launching of New Windows
SaveFileDialog
Cross Domain Access
File System & Registry Access
Drag & Drop
XAML Serialization (via XamlWriter.Save)
UI Automation Clients

Web Integration

Windows Communication Foundation (“Indigo”)
Windows Workflow Foundation
Scripting
Document Object Model (DOM) exposure/access

General Integration

HwndHost
Full Speech Support
WindowsForms Interop (“Crossbow”)

Visuals

BitmapEffects
Image Encoding

Editing

RTF Clipboard
Full XAML Clipboard Support

 

Vocabulary/Drill Downs

  • Site of Origin or Same Site Access.
  • Simulated Drag/Drop
    • OLE Drag/Drop is not enabled in V1.
    • App developers can simulate INTRA-app drag/drop using MouseCapture & MouseMove.
  • Browser Download Dialog
    • Browser-specific download dialog shown when navigating to a file whose HTTP header has ’Content-Disposition: Attachment’
    • As SaveFileDialog is not available in V1 sandbox, Browser Download Dialog is possible workaround.
  • IsolatedStorage
    • Data storage mechanism that provides isolation & safety.  (More details.)
    • Place to store data between sessions.
  • Partial XAML Clipboard Support
    • Copy/paste of content between two Internet XBAPs will copy/paste XAML.
    • Copy from a Internet XBAP in to a full trust WPF application will paste plain text.
    • Copy from a full trust WPF application in to an Internet XBAP will paste XAML.
    • Note: this constraint is to prevent escalation of privilege attacks using the clipboard.
  • User Initiated Paste
    • Programmatic paste is disallowed in the sandbox.
    • Only Ctrl-P & Paste Menus (context menu, browser menu) will result in a paste.
  • User Initiated Top Level Navigation
    • A navigation is top level if it is to content external to the application. 
    • Example:  <Hyperlink NavigateUri=”http://foo.com>Link</Hyperlink>
    • A user initiated navigation is a navigation that results from a user click on a <Hyperlink> element.
  • Media (Site of Origin & Cross Domain)
    • Rendering & bits/pixel access to site of origin images/videos/audio.
    • Rendering (but not bits/pixel access) to cross domain images, with below constraints.

Healthcare Application – Source Code Posted!

Source code for the Contoso Healthcare Application is now posted on the community site! (Thanks Karsten!)

This is a great app. (I demoed it at TechEd Southeast Asia & its been shown at many other events as well).  It showcases, among other things:

  1. 3D fliptransitions.  (This UX paradigm is similar to a doctor’s real world experience of flipping through a patient chart.)
  2. Data visualization on a 3D surface for fast comparison.
  3. Listbox styling dependent on level of information desired.
  4. Annotations on video.
  5. Patient diagnosis in flow document format.

Get the code here.

FontPlayer XBAP

I thought it would be fun to update the UI (and some functionality) for the FontPlayer SDK sample. This app lets you to play with the fonts installed on your the machine. It also shows off the OpenType features of specific fonts.

Some of the interesting features that I added to this app:

  • Embedded fonts in XBAP
  • ComboBox bound to system fonts, displayed using font
  • New CheckBox template
  • Text “reflection” effect

FontPlayer works with RC 1. Run it here. Code found here.

Screen Shots – Details


custom font


font ComboBox


new CheckBox template

Embedded fonts in XBAP
Custom fonts are a great way to brand the look & feel for your app. WPF’s embedded font support means I can use a custom font in a web app without affecting/installing system fonts.

In this app, I’m using Robby’s custom font, Ingebretsen Neato. To accomplish this, I included “Ingebretsen Neato.ttf” in the project and then referenced it in this style:


  <Style x:Key="Heading" TargetType="{x:Type TextBlock}"  >
    <!– Custom font from http://notstatic.com -->
    <Setter Property=”FontFamily”
        Value=”./Resources/#Ingebretsen Neato” />
    <Setter Property=”FontSize” Value=”20″ />
    <Setter Property=”Foreground” Value=”#FFFFFFFF”/>
    <Setter Property=”HorizontalAlignment” Value=”Center”/>
  </Style>

The text team’s blog has a lot more info about fonts & typography if you’re interested.

ComboBox bound to system fonts

The XAML to create a ComboBox bound to the system’s font:


  <ComboBox Name="FontFamilyComboBox"
    ItemsSource=
       ”{Binding Source={x:Static media:Fonts.SystemFontFamilies}}”
    ItemTemplate=”{StaticResource FontFamilyTemplate}”
    SelectionChanged=”FontFamilySelectionChanged”
    Width=”150″ HorizontalAlignment=”Center”
  />

In order display the font names in the actual font, I used a data template w/ a type converter.


  <local:FontFamilyToStringConverter x:Key="FontFamilyToString" />
  ...
  <DataTemplate x:Key=”FontFamilyTemplate” >
    <TextBlock
      Text=
        ”{Binding Converter={StaticResource FontFamilyToString}}”
      FontFamily=”{Binding}”
    />
  </DataTemplate>

The type converter was defined in the code-behind file:


  public class FontFamilyToStringConverter : IValueConverter
  {
    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
       FontFamily fontFamily = value as FontFamily;
       return fontFamily.ToString();
    }
    ...  
  }

New CheckBox template

I thought that a new look & feel for the CheckBox would more sense for toggling the options. I based the control template on Robby’s SimpleStyles. I then animated the opacity of the OptionsGrid based on the CheckBox.Checked event.

To see it, look at ResourcesCheckBox.xaml.

Loose XAML, XBAPs & Hyperlink Images

As Mark Alaczar points out in his WPF sandbox whitepaper, sandboxed top level navigation requires user initiation.

Some definitions to help this make sense:

  • Top level navigation: Navigations that target the hosting web browser. For instance, navigating the entire browser, or a specific HTML <iframe>, to http://netfx3.com.
  • User initiated: Direct result of an explicit user action. In the case of top level navigation, this is most likely the user clicking on a hyperlink. “Programmatic”, on the other hand, is the direct result of a dev action, like NavigationService.Navigate(…).

In this version of WPF, top level navigations in sandboxed apps require “user initiation.” Today, only the Hyperlink class has this notion of “user-initiatedness,” and it cannot (for security reasons) be subclassed in the internet sandbox.

There are many cases, however, where a more interesting Hyperlink than the default is desired. This post uses styling to create an image hyperlink that works in the internet sandbox.

Hyperlink is an inline-level flow content element that derives from TextElement, not ContentControl. This means it must be put inside of a text element container like Paragraph or TextBlock.

To create a more general control that can be used in different layout containers, you can use a ContentControl with the following style:

<ControlTemplate TargetType="ContentControl" x:Key="Hyperlink">
  <TextBlock Text="" TextWrapping="Wrap">
    <Hyperlink TextDecorations="" NavigateUri="http://www.netfx3.com">
      <Image Style="{StaticResource HyperlinkImage}">
      </Image>
    </Hyperlink>
  </TextBlock>
</ControlTemplate>

You can than style the image, perhaps adding a mouse over trigger:

<Style x:Key="HyperlinkImage" TargetType="{x:Type Image}">
  <Setter Property="Source">
    <Setter.Value>
      <BitmapImage UriSource="flowers_color.jpg"/>
    </Setter.Value>
  </Setter>

  <Setter Property="HorizontalAlignment" Value="center"/>
  <Setter Property="VerticalAlignment" Value="center"/>
  <Setter Property="Stretch" Value="Uniform"/>
  <Setter Property="IsEnabled" Value="true"/>

  <!-- Hover Trigger to change image source-->
  <Style.Triggers>
    <Trigger Property="Image.IsMouseOver" Value="true">
      <Setter Property="Image.Source">
        <Setter.Value>
          <BitmapImage UriSource="flowers_bw.jpg"/>
        </Setter.Value>
      </Setter>
    </Trigger>
  </Style.Triggers>
</Style>

Then create the ContentControl itself:

<WrapPanel Margin="40" Orientation="Vertical">
  <ContentControl  Width="100" Template="{StaticResource Hyperlink}"/>
</WrapPanel>

You can try it out in loose xaml here.

XBAPs: OnDemand & ClickOnce

If your XBAP has some “heft” to it (large resource files, large assemblies, etc), it may make sense to architect your app to use ClickOnce’s OnDemand APIs.

OnDemand APIs enable developers to delay download parts of the application. This can result in a friendlier end-user UX. Note: OnDemand files can be traditional resource files (e.g. images, xml files, etc) or assemblies.

Architecture Tips & Tricks
Got satellite assemblies or large resource files? Slim down your primary EXE to the bare minimum needed to start the app. Then, when the XBAP is launched, only the application manifest, deployment manifest, and primary EXE will be downloaded. As the user navigates around the xbap, you can use a second thread to download other files/assemblies silently in the background or show app-specific progress UI.

The Sample
I’ve created a sample XBAP that does just this:

  1. Has slim primary EXE.
  2. Utilizes 4 large image files and a controls dll. (Approx 3MB)
  3. When user navigates to xbap, she sees a landing screen while the controls dll & images are being downloaded on separate thread.

The major implementation steps are:

  1. Include resource files (i.e. images) as Content not Resource.
  2. No change to control assemblies.
  3. On the project properties page, select the publish tab. Click the Application Files button. Put the “OnDemand” files in to a separate group. (NOT “Required”.)
  4. Add a reference to System.Deployment
  5. Call the OnDemand Deployment APIs on a separate thread.

Try it out the xbap (RC 1). Get the code here.

Note: OnDemand APIs should only be called when applications are actually deployed using ClickOnce, not during F5 debug.

Pretty Illustrations
Step 1 above: Setting resources files as Content

 Step 3 above: Setting resources files as Content

More Resources

  1. MSDN ClickOnce Deployment and Localization
  2. MSDN ClickOnce OnDemand Deployment Technology Sample
  3. MSDN Walkthrough: Downloading Assemblies on Demand with the ClickOnce Deployment API Using the Designer

Caching & XBAPs

When relying on resources living on a server, you can increase client app perf & decrease network traffic by storing local versions. When trying to build a sandboxed XBAP, however, you cannot create your own local cache store in the file system beyond the space available in isolated storage (512KB).

Fortunately, WPF resource loading uses System.NET’s HttpWebRequest and its “Default” caching policy. In addition, depending on your resources’ sizes and your scenario, it may make sense to use a non-default caching policy when issuing your own HttpWebRequest.

This post aims to give you a little bit of caching context, an overview of your caching options and some sample code.

Understanding the HTTP Cache

How long is something good for?
This answer is determined through a combination of server & client settings.

The server sets the HTTP Response Header “Expires” to indicate the time after which a resource is considered stale. A stale cache entry may not normally be retrieved unless it is first validated with the origin server as being the current version. In addition, the server may specifiy certain cache directives in the header. These include “no-cache,” “max-age,” and “must-revalidate.”

The client/app’s cache policy can determine whether or not a “stale” or even a “not yet stale” value should be returned. Some of these policies are time based (e.g. “okay if stale only for X days”) or location based (“return cached value if it’s there and meets server specified revalidation requirements.) However whatever the app’s cache policy, it must respect the server’s cache directives.


System.Net’s Cache
System.Net.HttpWebRequest’s cache uses the IE cache. This has many benefits: there is a single place for user management perspective. Also, a shared store widens the chance that a recent response might have already been cached. The IE cache (“inet cache”) uses the Temporary Internet Files (“TIF”) to cache results of HTTP requests. Some details:

System.Net.HttpWebRequest’s cache uses the IE cache. This has many benefits: there is a single place for user management perspective. Also, a shared store widens the chance that a recent response might have already been cached. The IE cache (“inet cache”) uses the Temporary Internet Files (“TIF”) to cache results of HTTP requests. Some details:

  • (Update 11 Oct 06)The TIF is by default 3% of the harddrive on XP and 50MB on Vista. This amount is user configurable.
  • The TIF is clearable by users through the Internet Options control panel. It is scavenged when full.
  • On Vista, IE7 Protected Mode puts Low Integrity Level content in a separate cache.

Understanding the most common cache matrixes
The below table calls out some of the most common caching policies. (Note: We assume that no additional server cache constraints were set other than Expires header.)
Cache Policy
Note: If the server does not set the Expires http header, than the expiration=none. In this case, the machine determines what the right “Freshness” time for the resource. By default, this is 1 day but it is configurable.

Note: For System.Net.HttpWebRequest, “Default” policy is somewhat misleading. Unless you explicitly set HttpWebRequest.CachePolicy (or HttpWebRequest.DefaultCachePolicy), the policy is “BypassCache.”

What cache version to use
If your resource files are large & unlikely to change (and having current version is not critical), you should consider:

  • Set a large value in your resources HTTP Expires header
  • Set cache policy to HttpRequestCacheLevel.Default.

If it is critical to have the current version of the resource, you should consider:

  • Set cache policy to HttpRequestCacheLevel.Revalidate.

If you don’t want a unique caching policy, you should stiil:

  • Manually set the cache policy to HttpRequestCacheLevel.Default when creating your own HttpWebRequests

How to set cache policy
Here is a code snippet:

      //  eCreate request
      HttpWebRequest request =
         (HttpWebRequest)WebRequest.Create(requestURI);

      //  Create & set cache policy
      HttpRequestCachePolicy cachePolicy =
         new HttpRequestCachePolicy(HttpRequestCacheLevel.Default);
      request.CachePolicy = cachePolicy;
 
      //  Send request/Get response
      HttpWebResponse response = (HttpWebResponse) request.GetResponse();

      //  Put response in to stream
      Encoding enc = Encoding.GetEncoding(1252);
      StreamReader responseStream =
         new StreamReader(response.GetResponseStream(), enc);

      //  Manipulate Response stream
      //  Cleanup
      response.Close();
      responseStream.Close();


 Resources to more deeply understand standard caching