Partager via


Authorization Sample 101

This is an introduction to the Authorization Sample for RIA Services.

Authorization is implemented using attached properties. This means you can mark nearly everything in your xaml files with Authorization properties. In most cases, elements will be prepared for authorization and hidden until the framework determines access to that element is allowed. This section shows the basic markup and talks about how to use it.

For each sample, I’m assuming the following xml namespace has been added to the file. I’m using ‘s’ for ‘security’ as well as brevity.

  xmlns:s="clr-namespace:FirstLook.ServiceModel.DomainServices.Client.Security;
          assembly=FirstLook.ServiceModel.DomainServices.Client.Security"

RequiresAuthentication

The RequiresAuthentication property can be used to hide an element until the user is authenticated. This snippet will only show the hyperlink to authenticated users.

  <HyperlinkButton NavigateUri="/Accounts"
                  s:Authorization.RequiresAuthentication="True" />

RequiresRole

The RequiresRole property can be used to hide an element unless the user is in a specified role. This snippet will only show the hyperlink to users in the ‘Administrator’ role.

  <HyperlinkButton NavigateUri="/Accounts"
                  s:Authorization.RequiresRole="Administrator" />

The RequiresRole property also accepts multiple roles as input. In this snippet, the hyperlink will be shown when the user is in the ‘Administrator’ or ‘Manager’ roles.

  <HyperlinkButton NavigateUri="/Accounts"
                  s:Authorization.RequiresRole="Administrator,Manager" />

The NavigationMode property is used to enable authorization-based navigation. It can be applied to a Frame to enable authorization. The following snippet will redirect the user to ‘/Home’ if they attempt to navigate to a page they are not allowed to access.

  <nav:Frame Source="/Home" s:Authorization.NavigationMode="Redirect" />

Each page can simply declare its access rules using the RequiresAuthentication and RequiresRole properties discussed above. This snippet shows a page that can only be accessed by authenticated users.

  <nav:Page s:Authorization.RequiresAuthentication="True" />

[Security Note]

Authorization in Silverlight should only be used for Navigation and UI Customization. For true security, you need to secure your data by adding authorization to your web services. These msdn links describe how this can be done using WCF RIA Services.

https://msdn.microsoft.com/en-us/library/ee707361(v=VS.91).aspx

https://msdn.microsoft.com/en-us/library/ee707357(v=VS.91).aspx

Comments

  • Anonymous
    May 26, 2010
    Kylemc : A Hugeeeeeeeeeeeeeeeeeeeeee thank you a lot!  You help me so much! ABout a Business Application, when I click to logout (on the right upper), do you know how to redirect to my mainpage.xaml?

  • Anonymous
    June 02, 2010
    You can subscribe to WebContext.Current.Authentication.LoggedOut in MainPage.xaml.cs and navigate the ContentFrame to "/Home" whenever it occurs. If you're using this library and using authorization on pages, though, it will do it automatically for you.

  • Anonymous
    June 10, 2010
    This is great!!!  I have been pulling my hair out trying to figure out how to do this with VS2010, .net 4 and Silverlight in the predefined Business Application that you can use.

  • Anonymous
    June 18, 2010
    Kyle, great job, just what I was looking for. I have an issue however I'd like your advice on. In my bus app I'm using navigationmode prompt. This is exactly what I want for my registered users home page that can be navigated to from the anonymous homepage. When one actively logs out (with the logout link) while on a registered users' page, the login form popups. Obviously this is unwanted behaviour. How do I combine both navigationmode prompt AND redirection to e.g. the anonymous homepage? Thanks in advance for your help!

  • Anonymous
    June 22, 2010
    @Aleczander There are two approaches you can use. First, in my authz sample, I'm using active and passive logout (responding to session timeout). This complicates things as you'd only really want to return to the homepage on active logout. Since I'm using the BAT, I could do this by adding redirection to the LogoutButton_Click handler in LoginStatus.xaml.cs. NavigationService.Navigate(...) should work. The second approach is a little easier and works if you're only using active logout. In MainPage.xaml.cs you can subscribe to the Logout event on WebContext.Current.Authentication and navigate the ContentFrame to the homepage.

  • Anonymous
    June 23, 2010
    Hi Kyle,   I have a main page(main.aspx) with a logout button. This mainpage hosts another page postpage.aspx which contains some aspx controls and silverlight content when i click on logout button(which is aspx button) my silverlight content stil remains active and the page is not getting redirected but this is not happening with other pages ? any clue on this...... Thanks, Naresh

  • Anonymous
    June 23, 2010
    @Naresh Sorry, not much of a clue. You'll have to manually communicate between ASP.NET and Silverlight. The beginning of this msdn article shows how to get started (msdn.microsoft.com/.../cc135987.aspx). When logout is pressed on the main page, your post page will need to trigger a method in your silverlight application that calls WebContext.Current.Authentication.LoadUser(). If you can do that, the silverlight content will pick up the new (anonymous) user data.

  • Anonymous
    June 30, 2010
    Hi sir, Nice artical. After logout applicaiton is not redirecting the user to home page. am i missing anything. please help !!!

  • Anonymous
    July 01, 2010
    @Shailendra Take a look at my response above where I answered a very similar question. I'll summarize it again for clarity. You have two options:

  1. Redirect in LogoutButton_Click handler in LoginStatus.xaml.cs. The following code should work.    NavigationService.Navigate("/Home")
  2. In MainPage.xaml.cs, subscribe to the Logout event on WebContext.Current.Authentication. Redirect in the handler with the following code.    ContentFrame.Navigate("/Home")
  • Anonymous
    July 01, 2010
    Thanks.. it is working superbly ............ :)

  • Anonymous
    July 04, 2010
    Hello, Thanks for this control. I'm having a weird problem with it though when using Firefox (everything works fine in Internet Explorer): When navigating to a secured View for the first time I'm getting this Error: bei System.Windows.Navigation.PageResourceContentLoader.EndLoad(IAsyncResult asyncResult)   bei FirstLook.ServiceModel.DomainServices.Client.Security.AuthorizationContentLoader.HandleLoadCompleted(IAsyncResult asyncResult)   bei System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)   bei System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args) Caused by: Ein Aufrufziel hat einen Ausnahmefehler verursacht. (~"Call-Target caused an exception") After the second call the View works. This is happening even when logging in before navigating to the view. I'm using the "Prompt"-Option on the Navigation-Frame. Thanks

  • Anonymous
    July 05, 2010
    Ok the bug seems to be specific to the new Firefox Version (3.66, maybe even earlier). With my particular View it is appearing even when the View is not secured. No Problems with IE, Chrome or Firefox 3.59 for that matter. Guess I'll have to wait for a fix from Mozilla. Thanks again for your Lib.

  • Anonymous
    August 08, 2010
    I would also like to thank you for providing this model for security.  I was hoping that something simular would have been created in Silverlight but was not able to find anything or at least nothing yet.  As soon as I added your FirstLook.* to my project, the application behave the way that I had hope it would.  Once more, that you for providing this information... James

  • Anonymous
    August 11, 2010
    Bravo, great job !

  • Anonymous
    August 11, 2010
    hello where can i load your librairy ? thx

  • Anonymous
    August 11, 2010
    @Chris The library is included with the sample (linked above). This link will take you directly to the download page. code.msdn.microsoft.com/.../ProjectReleases.aspx

  • Anonymous
    September 02, 2010
    This is a great library! Is there a way to check that a user is in a specific role each time a new View is navigated to? I run a check User.IsInRole("myrole") but the profile doesn't pick up any changes made to the users' roles, e.g. I remove a user from the "administrator" role which should trim some menu items and deny access to certain pages, however this isn't picked up unles the user logs off / on again. I also use the annotation [RequiresAuthentication] and [RequiresRole roles...] but this doesn't appear to have any effect. Is there a way to resolve this?

  • Anonymous
    September 03, 2010
    @Michael The answer is not so simple. I think you're asking "If an administrator changes a user's access rights, how does that get checked in the Silverlight application?" The Silverlight application doesn't reload the user's credentials from the server because it has no idea they have changed. This case shows why it's important to protect your data as I describe in the security note above. You could do this manually (using WebContext.Current.Authentication.GetUser()), but the challenge is how to determine if updates have been made. There's an alternate question of "If I reload user Roles with logging out and in, how can I update the UI?" The answer there is a bit more advanced so I'll only answer it if you're interested.

  • Anonymous
    September 03, 2010
    Hi Kyle, you're right in your assumption. I am defintely interested in your alternate question of logging the user out / in. I have been playing around with AuthenticationService.LoadUser() on each page load to force reloading of user roles then manually updating the UI. This could get pretty complicated if my scenario gets bigger. However since the AuthenticationService.LoadUser() call is async, the changes are obviously not reflected on that particular page load, but rather the next one or if I catch it on a button click usng the security technique as you mentioned (good practise anyway!). Or, is there a way to register an event and use PropertyChangedEventArgs to update the user's roles?

  • Anonymous
    September 06, 2010
    @Michael One simple solution is that you don't reload role changes. You could detect unauthorized access and ask the user to refresh their application (browser page). It's not the experience you were looking for, but how often will roles be changed while an application is running and what is the harm if they are? I think there're two steps to take for an actual solution. First, you'll need to write a custom AuthenticationSource and AuthenticationSourceFactory. In your custom source, you can subscribe to Property/Collection changes to the Roles property on User and re-Authorize whenever something happens. This will trigger the UI to update. The second step might be a little trickier. You could write your own page INavigationContentLoader that delays page load until Roles has been reloaded. The downside of that solution is that you'd pay for a delay for an uncommon scenario. An alternative might be to have some periodic refresher that prompts the user for credentials when a page gets disabled. I think you can play around until you get the behavior you like best, but it may take a few tries to figure it out. Also, if you have any more questions on the details of this approach, feel free to contact me via this blog.

  • Anonymous
    October 06, 2010
    The comment has been removed

  • Anonymous
    October 06, 2010
    @paul I haven't noticed a bug along those lines before, but I'll take a second look. Also, I can look at your app to see if the issue's there if you'd like me to. Just use the 'Email Blog Author' link above.

  • Anonymous
    October 10, 2010
    Hello sir, In my silverlight 4 application I am using the forms authentication and m setting the role of the user after authentication to administrator this is working fine. But after setting the RequiresRole property in XAML as below s:Authorization.RequiresRole="Administrator,Manager" its not working ..... Please help me by your guidance ... Thanks in Advance Shailendra

  • Anonymous
    October 26, 2010
    The comment has been removed

  • Anonymous
    October 26, 2010
    The comment has been removed

  • Anonymous
    November 08, 2010
    Hi, I'm having issues with this framwork in my SL4 Bus App. Bascially, I have everything working, except for the [RequiresRole] attribute in the MembershipService. When this is applied, I get an Access Denied Error thrown whilst debugging. If I let the app run as normal, the TimeoutHelper takes overs, fire LoadUser(), and the app logs out every time. If I remove the [RequiresRole("Administartor")] attribute, everything works fine. Whilst debugging, I found that the ServiceContect.User does not have the info of the logged in user. IsAutheniticated is false, ans the user is displayed as 'Generic'. So, for some reason, even though the client is happy with the current user, the server side is not. The Server side does not know a user is logged in, even though the log in process has completed successfully. Any help appreciated. Thanks

  • Anonymous
    November 08, 2010
    @mwint If the server doesn't think you're authentication, then you're not authenticated (regardless of what the client thinks). Typically this happens when you've failed to persist the authentication correctly in your AuthenticationService. I can take a look at your service if it would help. Just use the 'Email blog author' link above and I'll email you back.

  • Anonymous
    November 22, 2010
    Kyle, I must be a complete idiot as I have added both the namespace and the RequiresAuthentication exactly as in your example and i get this build error... I must have missed SOMETHING but i cannot see what it is :-( Error 1 The property 'RequiresAuthentication' does not exist on the type 'HyperlinkButton' in the XML namespace 'clr-namespace:FirstLook.ServiceModel.DomainServices.Client.Security; assembly=FirstLook.ServiceModel.DomainServices.Client.Security'. C:UsersAdministratordocumentsvisual studio 2010ProjectsSilverlightExperimentSilverlightExperimentMainPage.xaml 48 59 SilverlightExperiment

  • Anonymous
    December 01, 2010
    @JimD Make sure you're including the 'Authorization' part in 's:Authorization.RequresAuthentication'.

  • Anonymous
    January 15, 2011
    After login, How can i redirect the page depending on type of Auth - Role?

  • Anonymous
    January 16, 2011
    @streaky It depends on what your design is, but an easy way to do it would be to add a handler to the WebContext.Current.Authentication.LoggedIn event. In the handler you can navigate to the correct page.

  • Anonymous
    January 19, 2011
    sir, I have just gone through the sample you provided but I do not know where you got the MembershipServiceUser class utilised within MembershipService. I assumed you created it but when I did right click, go to definition, I see an Auto generated file. Please how can I create a service like yours (MembershipService) and utilise a class (MemberShipServiceUser) that just seem to get injected into the autogenerated file, yet I know all the members that the class should have. I assumed that the service had to be receiving entities from an entity data model but no such data model was available. thanks, Raymond

  • Anonymous
    January 19, 2011
    @Raymond It's defined on the server and then generated on the client. Take a look at "AuthorizationSampleAuthorizationSample.WebServicesMembershipService.cs" in the sample. Also, take a look at this post where I describe the MembershipService a little more. blogs.msdn.com/.../using-asp-net-membership-in-silverlight.aspx

  • Anonymous
    January 19, 2011
    I have found it. thanks, Raymond

  • Anonymous
    January 20, 2011
    thanks kylemc... that wokred.  I just didnt realize how exactly to hook it up at first being new to it all.  But I did get it working a couple days ago.. thanks for your help.

  • Anonymous
    January 24, 2011
    Hi Kyle, following your suggestion on navigation from LoginStatus.xaml.cs, I did this: NavigationService.Navigate("/Home"); but found out that the Navigate function was not available. I had to do NavigationService ns =new NavigationService(); ns.Navigate("/Home"); to get it to work. but I understand that creating a new Navigation service class would mean that the frame would not have this navigation in the history since it uses a different navigation service. did you mean that a new NavigationService should be created or am I missing something?

  • Anonymous
    January 25, 2011
    There's a NavigationService property on controls extending Page. From most controls you should be able to find either the containing Page or Frame using the FrameworkElement.FindName method.

  • Anonymous
    January 25, 2011
    Please could you show me how to find the containing page or frame for the LoginStatus as i still have not got it. thanks, Raymond

  • Anonymous
    January 25, 2011
    @Raymond It should be something like this. Frame contentFrame = (Frame)this.FindName("ContentFrame");

  • Anonymous
    January 25, 2011
    The comment has been removed

  • Anonymous
    January 26, 2011
    Hi, this is great library, but i have one problem. On one page it working excellent, but on another it throws me an error: There is no dependency property with the name 'VisibiltyProperty' on the target of type 'System.Windows.Controls.Button' to bind to. The xaml part looks like: <Button... sec:Authorization.RequiresRole="Admin" sec:Authorization.TargetProperties="Visibilty" /> Do you have any idea? Thanks in advance Best regards

  • Anonymous
    January 26, 2011
    Hi, everything works fine. It's my mistake.

  • Anonymous
    January 28, 2011
    Hi, first of all great solution! can I use it with Windows Authentication? I guess that I must set the NavigationMode always to "Redirect"... Right? Thank you!

  • Anonymous
    January 30, 2011
    @Windows Authentication Yes and Yes. Hope it helps.

  • Anonymous
    February 03, 2011
    This is awesome!  Thank you so much for posting this series, I've been looking for something like this for a while!  I've literally just downloaded and have not gotten any further than adding a few attributes just like in the 101 word document.  I've already noticed an odd behavior...if I require a role on a navigation page and set the navigation mode to redirect, it appears that it works and redirects me to the "Home" page, but it also appears that the page I was redirected away from loads and will run in the background, hidden so to speak.  Is this expected behavior?

  • Anonymous
    February 04, 2011
    @Mike I think I would expect the first Page to get instantiated, possibly loaded, but not navigated to (Page.OnNavigatedTo). This is mostly due to how the code leverages the default page loader. For your pages, I would recommend waiting for the OnNavigatedTo method to get called before performing actions like loading data or memory-intensive processing.

  • Anonymous
    February 15, 2011
    Kyle, Your blog has been a great help!  Nice work. I'm trying to create a RoleService similar to the MembershipService you created.  I need to be able to maintain the users and their roles from inside the Silverlight app. First, I assume that I do have to create a new svc to handle the roles, correct?  Second, I'm not really sure what all is needed in the service.  Do you have any pointers? Many Thanks, Kyle Parker

  • Anonymous
    February 17, 2011
    @Kyle I tried to describe my approach a bit more in this post (blogs.msdn.com/.../using-asp-net-membership-in-silverlight.aspx). Basically, you can do it in two steps. (1) Figure out what things you want to be able to do using the ASP.NET Roles API and (2) add DomainService operations that can be accessed securely that call into the Role API.

  • Anonymous
    February 17, 2011
    Kyle, I downloaded AuthorizationSample and tried to run it but got this message: "There was a failure using the default 'MembershipProvider'.  Please make sure it is configured correctly." Can you please advise how to fix it? THanks.

  • Anonymous
    February 18, 2011
    @Jim It's pretty tough to guess what's going on. It might be worth your while to read up a little on ASP.NET Membership (msdn.microsoft.com/.../yh26yfzy.aspx). The authorization sample just relies on the stock SQL providers for membership (msdn.microsoft.com/.../6e9y4s5t.aspx), roles, and profile.

  • Anonymous
    February 18, 2011
    Thx Kyle.  The poblem was casued by the SQL server stopped running for unknown reason.  However I'm still not able to use your library.  Am I supposed to add FirstLookl...dll to References folder in my silverlight app?  But after I added it, the compilation of the project will fail.  Any advice?

  • Anonymous
    February 21, 2011
    @Jim The assembly also relies on WCF RIA Services. Is that something you've installed and referenced in your project as well?

  • Anonymous
    August 08, 2011
    Hi, good post...Two-factor authentication (TFA, T-FA or 2FA) is an approach to authentication which requires the presentation of two different kinds of evidence that someone is who they say they are.thanks to share with us....

  • Anonymous
    November 14, 2011
    Hi, nice Thanks  for posting................!!!!!!!!! ....

  • Anonymous
    September 10, 2012
    Hi Kyle, regards for suh a Great post..... I have only one doubt that how can i use my custom database with this project? Also i am assuming that you are using aspnetb database, if not can you explain me on how you have used queries with database? i mean in which cs file? your response will be geatly appreciated... Thanks..

  • Anonymous
    September 10, 2012
    I want to use my own database, can you plz help me to accomplish it? Thanks.

  • Anonymous
    September 11, 2012
    @Paritosh Take a look at the sample here. It shows you how to do AuthN using something other than the aspnetdb. code.msdn.microsoft.com/Custom-Authentication-96ca3d20

  • Anonymous
    September 12, 2012
    Hi kylemc.... Thank you very much for sharing that code that helped me a lot.... in that code you have got the role of the current user, i want to extend this concept with proviing restriction on accessing methods of with specified role....Similar to "RequireRoles("Manager")".. I bit confushed on how to restrict it if my current users role is "Customer".... Please help me...and again that or spending your valuable time...

  • Anonymous
    September 24, 2012
    As with all the ASP.NET authorization things, if you want to use a custom database, you will need to write a custom provider. For example to use your database with the requires role attribute, you need to write a RoleProvider. msdn.microsoft.com/.../8fw7xh74(v=VS.100).aspx