Authorization Sample 201
The attached properties described in Authorization 101 will get you going. It may even be a long time before you need more. If you find yourself chafing at the limits, though, then this section is for you. It works through some of first customization steps most applications will find useful.
Custom Authorization
Authorization is implemented using AuthorizationAttributes. If you’ve used ValidationAttributes in Silverlight, this approach should feel familiar to you. Custom authorization can be added by simply extending the AuthorizationAttribute and implementing the IsAuthorized method. These attributes can then be applied to a navigation Page or any other type where authorization would be useful.
In addition to attribute-based authorization, rule-based authorization is also available for convenient use in xaml. To implement rule-based authorization, you will need to create a new class that derives from AuthorizationRule and override the GetAuthorizationAttributes method.
public class CustomAuthorizationRule : AuthorizationRule
{
public override IEnumerable<AuthorizationAttribute>
GetAuthorizationAttributes(object target)
{
return new[] { new CustomAuthorizationAttribute() };
}
}
You can now reference this authorization method from anywhere in xaml using the Rule property. The following snippet displays the hyperlink according to your custom authorization rule.
<HyperlinkButton NavigateUri="/Accounts">
<s:Authorization.Rule>
<my:CustomAuthorizationRule />
</s:Authorization.Rule>
</HyperlinkButton>
Custom Behaviors
You may have noticed not all elements are hidden when the RequiresAuthentication and RequiresRole properties are applied. Pages, for instance, are simply disabled. Even though the default behavior is determined based on element type, each element can specifically declare how authorization should be applied using the TargetProperties property. The following snippet disables the hyperlink for users who are not in the ‘Administrator’ role.
<HyperlinkButton NavigateUri="/Accounts"
s:Authorization.RequiresRole="Administrator"
s:Authorization.TargetProperties="IsEnabled" />
The TargetProperties property can be set on an element to any DependencyProperty that is a type supported by the AuthorizationConverter. Most notably, these types include Strings, Booleans, and Visibility. Also, like RequiresRole, the TargetProperties property supports a comma-separated list of property names.
NavigationMode.Prompt
Sometimes simply redirecting the user when they try to access a page they are not allowed to view is not the best option. Often, it is useful to prompt the user for their login credentials. If you set the NavigationMode to Prompt, the framework will attempt to do just that.
Using Prompt mode requires you to implement an AuthorizationPrompter, a simple interface used to prompt the user for credentials. A single instance can be created at startup and will be used throughout.
public App()
{
// ...
Authorization.Prompter = new LoginRegistrationWindowPrompter();
}
Additionally, a Page and Frame can specify different NavigationModes. The value specified by the Frame will be used as the default. If a Page chooses to specify a value as well, it will be used instead of the default.
Comments
Anonymous
October 15, 2010
what's LoginRegistrationWindowPrompter? how to define?could you give me a link to sourcecode? 568264099@qq.com or facingwaller@gmail.comAnonymous
October 19, 2010
The source code for this sample is available here. blogs.msdn.com/.../silverlight-authorization-sample.aspxAnonymous
January 19, 2011
Great stuff Kyle. Is there any tricks to getting the NavigationMode="Prompt" to work in the AuthorizationSample project? I've tried a few combinations with Requires Role & Authentication and TargetProperties, but I think this basic scenario should prompt with a Login dialog if the user isn't authenticated? <HyperlinkButton x:Name="LinkAbout" Style="{StaticResource LinkStyle}" s:Authorization.NavigationMode="Prompt" NavigateUri="/About" TargetName="ContentFrame" Content="About Us"/>Anonymous
January 19, 2011
Also... After digging around looking for straightforward methodology for page level security, it seems this approach should be included in the next Silverlight release directly...Anonymous
January 19, 2011
@Matt Thanks. NavigationMode is only designed to be set at a Frame level (and optionally overridden at the Page level). Using it with any other controls won't work. So there are really three steps to take for each page.
- Make sure the containing Frame has a NavigationMode specified
- Add authorization to the Page
- Add authorization to Hyperlinks that navigate to the page
Anonymous
January 20, 2011
The comment has been removedAnonymous
April 08, 2011
Kyle this is once again amazing stuff. Just interestingly, I do get a warning: base type 'FirstLook.ServiceModel.DomainServices.Client.Security.AuthorizationPrompter' is not CLS-compliant Code does compile and work flawlessly.Anonymous
May 16, 2011
I get the same CLS-compliant warnings. What's up with that?Anonymous
August 21, 2011
HI, It is easy to confuse the mechanism of authentication with that of authorization. In many host-based systems (and even some client/server systems), the two mechanisms are performed by the same physical hardware and, in some cases, the same software.nice oneAnonymous
October 02, 2011
The comment has been removedAnonymous
October 03, 2011
The redirect is baked in to the library. It should be sending you back to the page you default your frame to. Here's the VB equivalent of the code above and it's important to include it in the prompter. window.Closed += Function(sender, e) completionCallback(userState)Anonymous
October 17, 2011
Hi, In my application when app loads,login is prompted. ie,on http://localhost:2555/AuthorizationSampleTestPage.aspx#/Home page, login child window pops.After sucessful login i click a link to redirect to 'about' page. ie,http://localhost:2555/AuthorizationSampleTestPage.aspx#/About. It works fine. But when the copy the above link and paste it to another tab, About page comes with login prompt. I mean login is prompted although the app get redirect to about us page. I can see the about page in background. So my question is how can i remain in Home page when i copy the 'about' page link in browser if i am not authenticated?Or when I paste a link to another page I should get redirect to first page,if i am not authenticated.Anonymous
October 17, 2011
@ajin If you want the default behavior to redirection, but you want prompting on the home page (or vice versa), then you should be able to set the default NavigationMode on the Frame and set exceptional NavigationModes on specific pages. The authorization logic is based on the current value in WebContext.Current.User. When you navigate in using a deep link, you need to make sure that value is up-to-date. Typically you'd call WebContext.Current.Authentication.LoadUser() and wait for it to return before loading the page with the navigation frame (for instance, you could make the call in App.xaml.cs before making MainPage the RootVisual.Anonymous
October 23, 2011
''s:Authorization.TargetProperties''. i cannot access the Targetproperties . cannot resolve targetproperties error.Anonymous
October 24, 2011
Have you added the following to the xmlns includes? xmlns:s="clr-namespace:FirstLook.ServiceModel.DomainServices.Client.Security; assembly=FirstLook.ServiceModel.DomainServices.Client.Security"Anonymous
October 24, 2011
The comment has been removedAnonymous
October 25, 2011
@Olly In the prompter, it's important to invoke the callback. If the prompter opens a window, then it's easiest to invoke the callback in the Closed event. How exactly you choose to do this is up to you. In my response to ajin on the 18th, I explain why this happens. Typically you'll want to fix it by loading the user in App.xaml.cs.