(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

WCF RIA Services Part 7 - Authentication and Authorization

(12 votes)
Brian Noyes
>
Brian Noyes
Joined Jun 10, 2010
Articles:   19
Comments:   116
More Articles
76 comments   /   posted on Sep 15, 2010
Categories:   Data Access , Line-of-Business

This article is Part 7 of the series WCF RIA Services.

Introduction

In this article, I’ll focus on the security capabilities of WCF RIA Services. Security is one of the areas where RIA Services took something that is vitally important to an application and can be very complex when using WCF on its own, and gave us a simple to use approach that covers 80% of the cases with minimal code and confusion, while still covering most of the remaining 20% nicely with the extensibility hooks in RIA Services for security. Like many other aspects of RIA Services, you are insulated from the service level plumbing that needs to happen to secure your communications and calls and just lets you focus on putting the checks and balances in place to make sure that only things that are supposed to happen in your application are allowed.

There are three concerns to focus on with service security: authentication, authorization, and transfer security. Authentication is simply the act of identifying the caller and determining if you believe they are who they say they are. Authorization is determining what you are going to allow them to do once you know who they are. And transfer security has to do with protecting the messages when they hit the wire so that someone cannot view or tamper with the messages enroute. In addition, you have client side security concerns in that you may not want anyone to be able to run your Silverlight application, and when they do, you want to know who they are both so you can make the service calls and to authorize different functionality on the client side. RIA Services has built-in functionality to cover all of these based on proven and standardized protocols and based on the pre-existing infrastructure of .NET for security.

On important thing to understand is that the security model of the service calls from your Silverlight client to your domain services is a separate thing from the security provided by the hosting web application. When your Silverlight application launches initially in the browser, the host web page is first accessed from the site. Then your XAP is downloaded as a file and launched on the client side. After it launches, the application can make RIA Service calls to the back end, and those calls first manifest themselves on the server side as HTTP requests for an svc file to the web server. This process is shown in the figure below.

9-10-2010 2-15-37 PM

The security of those calls is determined by the configuration of the hosting web site, which may demand Windows or Forms authentication itself to restrict access to the files. You could choose to rely entirely on site level security, but often you need to have more explicit points of control inside your client and service code where you need to know who the user is and what you are going to allow them to do. This is where RIA Services security steps in and gives you the control you need, both server and client side.

WCF RIA Services security allows you to:

  • Leverage membership and role providers configured at the host site to do the authentication and authorization look ups (as well as tie into the Profile system if desired)
  • Use Windows or Username/password credentials out of the box, or other credentials using the extensibility hooks
  • Declaratively perform authentication and authorization checks on the server side
  • Have a client side security context for knowing if the user is authenticated, what their identity is, and what roles they are associated with
  • Perform custom authentication and authorization steps on client or server side through the extensibility hooks
  • Enforce protection of the messages through SSL

The really quick way to start an application to use WCF RIA Services security is to use the Silverlight Business Application project template. That template sets up all the all the configuration and services stuff that I am going to walk through in this article by default. But I don’t think you should use any capability without understanding what it is doing for you, especially with something as important as security. So I am going to walk through the mechanisms to set it up manually so you understand what you need and what the different pieces do for you.

So lets dive right in. You can download the completed sample code for this article here.

Authenticating the User

The most common scenarios for authenticating the user include using either Windows credentials or using a username/password (username credentials). For the Windows case, you may require the user to enter a domain account on the client side because they could be working from a home or public computer that is not part of the domain, or you might leverage integrated security to have the hosting browser or application send the Windows credentials automatically. For the username case, you may be validating the username against a database, LDAP or other custom store. In both of these cases as long as you don’t need to do anything too fancy, it can be extremely simple to set up by letting the host web site and browser do the heavy lifting for you. You could choose to authenticate the user in an ASP.NET web page to establish a forms authentication session before you launch the Silverlight application. Doing so would let you secure access to the XAP file download as well as the svc file service calls just based on web site security without doing anything inside of your Silverlight app. Or you could allow unrestricted XAP file download and launch, and then authenticate the user after the Silverlight app launches. There are many options supported by Silverlight itself here, regardless of whether you are using WCF RIA Services or not.

On top of the basic security mechanisms of the host site and Silverlight, you may want to have specific points of enforcement in the service calls on the back end. Additionally, you often need to know who the authenticated user is on the client side, as well as what roles they are in, to modify the behavior of the client application appropriately (i.e. hide or disable commands that the user is not authorized to invoke). Natively in Silverlight, there is no security context, even if the application launch happens as part of a secure session in the browser. The threads do not have security principals on them like in a normal .NET application that could tell you who the authenticated user is. WCF RIA Services steps in here for us and provides the infrastructure to not only authenticate the calls on the server side, but to also return the authentication and authorization context to the client so that you can easily address these scenarios.

If you don’t need the client to know about the user and their roles, it is really simple to secure the back end with RIA Services. The first step is to turn on authentication in the web host site with either Windows or Forms as the mode.

 <authentication mode="Forms"/>

Once you have done this, RIA Services can use the configured or default membership provider to look up the username/password that are sent from the client to authenticate them. If you choose to use Windows credentials, those credentials would be validated by IIS itself through the OS. You can collect the user credentials in either case before the Silverlight application launches through a web login form that uses normal Forms Authentication to pass the user credentials in a cookie, or by using RIA Services to pass the credentials from within the Silverlight application. There is nothing special about configuring membership or role providers with respect to RIA Services. That topic has been well covered in many other places in the context of ASP.NET security or Silverlight itself. For a good walkthrough of how to configure things, see the configuration section of this walkthrough.

For this article, I am going to assume you want to provide the login experience as part of the Silverlight application, and that you will want the user identity and roles available on the client. That means you will need to expose the XAP file from the hosting web site for unauthenticated download unless you want to force the user to log in twice. If instead you want to authenticate via a web page AND you do not need to do any client side authorization or user customization, then you could just rely entirely on the server configuration and services code. But the richer scenarios enabled by RIA Services is what I want to focus on.

Step 1: Set up your Membership Provider

To minimize the amount of configuration required to run the sample code, I am using a custom membership provider that is part of the web host project. That provider works against the User table that is part of the TaskManager database. Additionally, that provider just expects the passwords to be stored in the clear in the database so that you can use a predefined account in the database (Username=Brian, Password=IDesign) with no set up. Naturally this is not what you should do in production. With a minor modification to the membership provider, you can hash the incoming password and compare to a hashed version in the database. This requires you to have a mechanism for creating the user accounts that will use the same hashing algorithm when creating the user account. Again, there are lots of examples out there of doing this, so I won’t cover that here.

The custom membership provider just uses the same Entity Framework model to look up username/password combinations to authenticate the calls. The custom membership provider looks like this:

 public class CustomMembershipProvider : MembershipProvider
 {
     public override bool ValidateUser(string username, string password)
     {
         using (TaskManagerEntities context = new TaskManagerEntities())
         {
             var user = context.Users.Where(u => u.Username == username &&
                 u.Password == password).FirstOrDefault();
             return user != null;
         }
     }
  
     public override string ApplicationName
     {
         get { return "TaskManager"; }
         set { }
     }
   
     // Other overrides not implemented
     ...
 }

At runtime, the only method in the provider that matters is the ValidateUser method. It will look up the credentials passed in and validate them. If valid, the membership provider and RIA Services will set up an authentication context on the server side. If you expose things right from your services, you can get that authentication context back in the client.

After you have defined your custom provider, or if you want to use the built-in SQL provider, you just need to configure the site for that provider:

 <system.web>
   <authentication mode="Forms" />
   <membership defaultProvider="myCustomProvider">
     <providers>
       <add name="myCustomProvider" type="TaskManager.Web.CustomMembershipProvider,TaskManager.Web"/>
     </providers>
   </membership>
 ...
 </system.web>

Now your site and RIA Services have enough information server side to authenticate the user with a username/password. However, you need a little more support client side to provide that information.

Step 2: Create an Authentication Domain Service

In order to have the right support on the client side to send the credentials and to establish a client side authentication context after successfully authenticating, you need to define an Authentication Domain Service as part of your host site. This is really a trivial matter unless you want to get into custom authentication scenarios because the RIA Services base classes provide you with everything you need for authenticating and authorizing through the membership and role providers.

To do this, just go to the host web site project, and add a new item to the project (right click on the project in Solution Explorer and select Add > New Item). From the Web category, select the Authentication Domain Service template. Name it TasksAuthenitcationDomainService. A class similar to the following will be added. The only modifications I made here are to remove some comments and change the name of the user class used by this service so it does not conflict in name with the one that is defined as part of our Entity Framework model.

 [EnableClientAccess]
 public class TasksAuthenticationDomainService : AuthenticationBase<AuthUser>
 {
 }
  
 public class AuthUser : UserBase
 {
 }

The AuthenticationBase class takes care of calling into the membership provider when the user logs in. Because this class is a domain service, a client domain context will be generated and gets tied in automatically with the other domain contexts so that they can secure their calls based on this authentication service as well. The UserBase class provides the basic information about an authenticated user such as the identity name, roles and so on. You can derive from this to add any user specific properties that you want to associate with the authenticated user. The authentication service will return an instance of that user type to the client side after successful authentication so that it provides the full context of who the user is and what they can do, in addition to whatever other user specific information you want to add on.

Step 3: Create a WebContext instance for use on the client side

Part of the client generated code includes a class called WebContext. This class gets enhanced after adding your authentication service to include a property called User of the AuthUser type used by the authentication service. The base class exposes methods for Login and other authentication and authorization related functionality. Even though this type gets defined through the code generation on the client side, you need to initialize the web context for the client and set its authentication type. To initialize the web context, you add an instance of it to the ApplicationLifetimeObjects collection of the App class in the App constructor after setting its Authentication property:

 public App()
 {
     this.Startup += this.Application_Startup;
     this.Exit += this.Application_Exit;
     this.UnhandledException += this.Application_UnhandledException;
  
     InitializeComponent();
     WebContext context = new WebContext();
     context.Authentication = new FormsAuthentication();
     ApplicationLifetimeObjects.Add(context);
 }

Step 4: Login the user

From there it is up to you to decide when and where to authenticate the user in the client application. But if you are going to secure the services, it needs to be before you start calling the domain services. In the TaskManager application, I went with the simplest, crudest approach. As the MainPage loads, it pops a ChildWindow derived pop up LoginForm that lets the user log in. If log in is successful, the tasks view is loaded. I factored out the XAML that was previously part of the MainPage markup into a separate user control called TasksView that I load into a ContentControl in the MainPage if log in is successful to defer the calls to the services until after login is successful. The code in the MainPage code behind now looks like this:

 public partial class MainPage : UserControl
 {
     public MainPage()
     {
         InitializeComponent();
         Loaded += OnLoaded;
     }
  
     private void OnLoaded(object sender, RoutedEventArgs e)
     {
         if (!WebContext.Current.Authentication.User.Identity.IsAuthenticated)
         {
             LoginForm login = new LoginForm();
             login.Closed += (s, e2) =>
                 {
                     TasksView view = new TasksView();
                     MainContent.Content = view;
                 };
             login.Show();
         }
    }

The LoginForm ChildWindow code looks like the following

 public partial class LoginForm : ChildWindow
 {
     public LoginForm()
     {
         InitializeComponent();
     }
  
     private void OKButton_Click(object sender, RoutedEventArgs e)
     {
         LoginOperation loginOp = WebContext.Current.Authentication.Login(
             new LoginParameters(UsernameTextBox.Text, PasswordTextBox.Text));
         loginOp.Completed += (s2, e2) =>
             {
                 if (loginOp.HasError)
                 {
                     errorTextBlock.Text = loginOp.Error.Message;
                     loginOp.MarkErrorAsHandled();
                     return;
                 }
                 else if (!loginOp.LoginSuccess)
                 {
                     errorTextBlock.Text = "Login failed.";
                     return;
                 }
                 else
                 {
                     errorTextBlock.Text = string.Empty;
                     DialogResult = true;
                 }
             };
     }
 }

The LoginForm code calls the Login method on the WebContext.Authentication property that was initialized in the App class. The user can only get past the login dialog if they successfully authenticate. If their credentials are invalid, the Login call will succeed, but the LoginSuccess property on the LoginOperation result will be set to false.

With this in place, you now have everything you need for end-to-end authentication and authorization in the client and services.

Step 5: Secure the services

All it takes to protect your domain services from unauthenticated users now is a single attribute: [RequiresAuthentication]. This attribute can be placed on the domain service class and all exposed operations on the class (Query, Insert, Update, Delete, and Invoke methods) will be protected. You can also place it at the method level if there are only particular methods you want to require authentication for. For example, in a product catalog scenario, you might allow anyone to query the catalog, but only specific users can modify the catalog.

For the TasksDomainService, I am securing all calls:

 [EnableClientAccess()]
 [RequiresAuthentication]
 public class TasksDomainService : LinqToEntitiesDomainService<TaskManagerEntities>
 {  }

A quick way to prove to yourself that the authentication is working is to override the Initialize method in your domain service and check the user identity on the context. You can also capture the authenticated user and use it a moment later when the domain service method is called.

 private IPrincipal _User;
 public override void Initialize(DomainServiceContext context)
 {
     base.Initialize(context);
     Debug.WriteLine(context.User.Identity.Name);
     _User = context.User;
 }

 

Authorization with RIA Services

Once you have verified who the user is, you may want to make decisions about what they can do, both server side and client side. To do so, you need to enable the role provider on the server side and have a configured role provider that will answer questions like “what roles is this user in” and “is this user in this role”. Then you can make role assertions on the server and client side and either prevent the user from executing some logic if they are not in the right role, filter data based on them not being in a particular role, or modify the UI based on their role.

Step 1: Define the role provider you want to use

Like the membership provider, you can use the default SQL Server provider, a Windows provider that is in the framework, or write your own custom provider. For the sample application, I wrote a simple custom provider. Like the membership provider, there is only one method you have to implement to support authorization at runtime, GetRolesForUser:

 public class CustomRoleProvider : RoleProvider
 {
     public override string[] GetRolesForUser(string username)
     {
         if (username == "Brian") return new string[] { "Manager" };
         else return new string[]{};
     }
  
     public override string ApplicationName
     {
         get { return "TaskManager"; }
         set { }
     }
  
     // Other overrides not implemented
     ...
 }

Step 2: Enable the role manager and configure the provider

In your web.config file for the domain services host, ensure the role manager is enabled and your provider is specified if not the default:

 <roleManager enabled="true" defaultProvider="myCustomProvider">
   <providers>
     <add name="myCustomProvider" type="TaskManager.Web.CustomRoleProvider,TaskManager.Web"/>
   </providers>
 </roleManager>

Step 3: Demand roles in domain service methods

To ensure that only users in a certain role are allowed to execute a particular domain service method, you use the [RequiresRole] attribute. It takes a params string[] of role names. For example, if only managers are allowed to add new customers, I can enforce that in the domain service like so:

 [RequiresRole("Manager")]
 public void InsertCustomer(Customer customer)
 {
 }

If you then add a customer on the client side and you are not in the Manager role, when SubmitChanges is called on the domain context, you will get an access denied exception:

9-14-2010 8-02-53 AM

Step 4: Filter data based on roles or the authenticated user

You might also need to filter what data is exposed based on who the user is or what role they are in. In the sample application, I have the requirement that users in the Manager role can see all Tasks, but other users can only see the tasks for which they are in the associated users collection (many-to-many relationship between Tasks and Users at the database).

To do this, I can use roles and user identity inside my domain service methods. The authenticated user was captured in the Initialize method described in the previous section. I can now modify the GetTasks method like so:

 public IQueryable<Task> GetTasks()
 {
     if (_User.IsInRole("Manager"))
         return this.ObjectContext.Tasks.Include("TimeEntries").
             Include("Customer").OrderBy(t => t.StartDate);
     else
     {
         return ObjectContext.Tasks.Include("TimeEntries").Include("Customer").
             Where(t=> t.Users.Where(u=>u.Username == _User.Identity.Name).FirstOrDefault() != null).
             OrderBy(t=>t.StartDate);
     }
 }
You can see that if the user’s role is Manager, all Tasks are retrieved as before (possibly filtered by the client side expression tree sent when the method is called), but if the user is not in the Manager role, the results are filtered server side to only return the Tasks for which they are linked as a user on that Task.

Step 5: Make client-side authorization decisions

If the user is not a Manager, then the Add Customer button on the client side should never be enabled in the first place (or possibly hidden) so that the access denied exception is never reached. To do this, you need to check the user’s roles on the client side. This is easy to do through the WebContext since it’s User property will be populated after authenitcation is complete.

The view model previously had a CanExecute handler for the AddCustomerCommand that was mistakenly driving enablement off of the selection of a Task. The adding of a customer is actually decoupled from the task selection, but now I want the command to be disabled if the user is not a manager. So I simply updated the CanExecute handler for the AddCustomerCommand in the view model to the following:

 private bool OnCanAddCustomer(object arg)
 {
     if (WebContext.Current.User.IsInRole("Manager"))
        return true;
     else
        return false;
 }

Since the authentication is complete before the view and view model load, the WebContext will already know who the user is and have the roles the user is associated with populated by the back end.

Requiring Message Protection

In the sample application, the data and credentials are all being passed in clear text when the messages go back and forth from the client to the server and back. Obviously that is not a good idea for security. When you are securing your site and using WCF RIA Services, you really need to use SSL to protect the messages. To enforce that the service does not get deployed without the protection of SSL, you can simple add a property to the [EnableClientAccess] attribute in your domain services:

 [EnableClientAccess(RequiresSecureEndpoint=true)]

Summary

In this article I have walked you through the core security features of WCF RIA Services that allow you to easily authenticate the user and authorize what actions they can take in the client and in the services. There are a number of additional things you can do including performing more complex authentication inside your authentication service and defining custom authorization attributes.

If you want more explicit control over the authentication process inside of your services, you can override the ValidateUser method on the AuthenticationDomainService derived class you add to your server project. Then instead of doing what the base class does – call out to the configured membership provider – you are in complete control inside of your service to do whatever lookup of the client credentials you need. The advantage of the membership provider approach is that the provider you write becomes reusable not only in a WCF RIA Services application, but can also be used with ASP.NET, WCF, and even WPF and Windows Forms clients through Client Application Services. The advantage to bringing it inside your domain services is that you can more tightly integrate the user object used for authentication and a domain object like the separate User type in the Tasks Entity Framework model. For a good article and example of that, see the BookClub RIA Services sample and the authenitcation and authorization posts by Nikhil Kothari.

You can download the sample code for this article here.

About the Author

Brian Noyes is Chief Architect of IDesign, a Microsoft Regional Director, and Connected System MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, DevTeach, and others. He is the author of Developing Applications with Windows Workflow Foundation, Smart Client Deployment with ClickOnce, and Data Binding in Windows Forms 2.0. Brian got started programming as a hobby while flying F-14 Tomcats in the U.S. Navy, later turning his passion for code into his current career. You can contact Brian through his blog at http://briannoyes.net/ or on twitter @briannoyes.


Subscribe

Comments

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Mahesh on Sep 16, 2010 21:29

    Hi Brian,

    In Step 4, in LoginForm childwindow code, you are putting LoginOperations errors inside a textbox(errortextblock).

    Can you show instead of this direct input , how to raise validationresults so that a validationsummary control can catch all validations like "incorrect username" or "wrong password"?

    Also is it possible to use MetaDataClasses on server side to put Validation  Attributes like <Required()>, etc?

    Otherwise this post is great!!!

     

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by daniel on Sep 17, 2010 03:48

    Hi. Good article as always.
    I have a question about sending custom data when logging in.

    the AuthenticationBase.Login method has 'string customData' parameter, but this field seems to be ignored. and since it is not a virtual method, I can't override it. Is there a way to send custom data along with ID/Password when calling this method?

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Kyle McClellan on Sep 17, 2010 19:06

    Great post Brian.

    @daniel

    You have to implement your own authentication service to take advantage of it.

    public class MyAuthenticationService : DomainService, IAuthentication<MyUser>

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Thomas t1 on Sep 28, 2010 16:35
    Very useful posts! What I cannot seem to figure out, is how to authenticate a stand-alone application (WPF/Windows Forms) against the domain service, any hints on how to acheive this would be very useful as the authentication for non-SL clients is not very well documented IMHO, feel free to prove me wrong :)
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Sep 28, 2010 16:40

    Thomas,

    Not really the right tool for the job in my opinion since you don't get any client side code generation to make the authentication service as useful. What you want to look at is "Client Application Services", which allows you to easily leverage Membership and Role providers in a different way in WPF and Windows Forms clients.

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Thomas t1 on Sep 28, 2010 16:52

    Thanks for the tip Brian, turns out it's simple after all :) One of the very useful features of WCF RIA, IMHO, is the ability to use the same domain service from Silverlight, ASP.NET and non-web applications, which I'll be able to do via the Client Application Services, thanks again!

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Thomas t1 on Oct 08, 2010 17:09

    Brian,

    I would like to moderate the "simple" statement in my last comment to "possible". Although it is possible to use CAS, the WCF Authentication Service provides services more compatible with WCF RIA. By using shared cookie management implemented in a WCF Message Inspector/Behavior it's possible to combine the two in a relatively seamless way. None of the WCF RIA samples I have found deal with this issue, maybe this could be a section in a future article that deals with distributed solutions/applications, where the primary client is Silverlight but also has secondary clients e.g. a desktop application.

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by eric yan on Oct 12, 2010 08:31

    brian,

    Can't wait for part-8 and part -9 and part-10 and 11...

    :)

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Cleyotn on Oct 13, 2010 12:04

    Sorry. I meant to write my message in this article:

    Hi,

    I would like to congratulate you on these articles. They are fantastic. Thanks for this brillant series of articles.

    I really would like to learn how to test WCF Ria services and other stuff.

    When are you planning to finish the remaining articles?

    1. Debugging and Testing WCF RIA Services Applications
    2. Structuring WCF RIA Services Applications
    3. Exposing Additional Domain Service Endpoints for Other Clients
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Oct 13, 2010 13:49

    Hi Cleyton,

    Answered in both places just in case... :) Sorry, but just have had some schedule conflicts and priorities recently delaying me. Will have Part 8 out by end of October and Part 9 and 10 in November.

  • schilders

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by schilders on Oct 14, 2010 01:23

    Hi Brian,

    Is it possible to use an ObjectDataSource in a Silverlight solution?  I'm creating a prototype for a customer, and they don't necessarily want a database, membership provider, etc. included in the prototype.  Yet, we want to demonstrate the Silverlight Business Application's login functionality, protecting some pages from unauthenticated users, etc.  How would you suggest we proceed with using authentication and not going with a SQL Membership provider?

    Thanks,

    Sid

  • hunsra

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by hunsra on Oct 27, 2010 20:30
    Hi Brian,

    Thank you for the excellent post.  It has helped to clear things up a bit for me.  I have a question related to the statements "... For the Windows case, you may require the user to enter a domain account on the client side because they could be working from a home or public computer that is not part of the domain ..." and "... You can collect the user credentials in either case before the Silverlight application launches through a web login form that uses normal Forms Authentication to pass the user credentials in a cookie, or by using RIA Services to pass the credentials from within the Silverlight application ..." you wrote in the post:

    If I want to use Windows credentials (i.e. a Windows username, domain, and password) instead of proprietary application credentials to authenticate users, but want to use the Silverlight application to collect them (rather than the browser), how would I get a WCF service to impersonate the given user?  I understand how I would implement the "ValidateUser" method in the CustomMembershipProvider class (call the Win32 LogonUser API), but I don't see how I would be able to impersonate the identity in a WCF service once the user has logged in.  Can you provide any insight?

    Thanks again!
    Randy
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Oct 27, 2010 20:52
    Randy, In combination with the membership provider you could not impersonate. Even though the credentials are being validated against Windows, you are not establishing a WindowsPrincipal on the thread, which is required for Impersonation. In fact, RIA Services never establishes a thread principal, instead keeping the authorization context in its own service context. You could potentially set up your own WindowsPrincipal and establish it in the Initialize method of the service based on the credentials. I don't have a working sample of that, but have done it in the past through the WindowsIdentity class.
  • hunsra

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by hunsra on Oct 27, 2010 21:20
    Brian,

    Thank you for the quick response.  So, if I understand you correctly, it's not possible to customize the AuthenticationBase<User> -based authentication domain service class in some way so that when its Login() method is called the user is impersonated, right?

    To use your suggestion about establishing a WindowsPrincipal in the RIA service, how would the service discover the credentials used during the login operation?  The DomainServiceContext object passed to the Initialize() method includes a User property of the IPricipal type, and that includes an Identity property of the IIdentity type.  But that only includes the user name, not the password.

    Thanks for any help you can provide.

    -Randy
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Oct 27, 2010 21:48

    Randy, since the AuthenticationService is a separate service, doing something there would not have an effect in the other services. That service just allows a security context to be set up that can then be returned to the client. In fact, if you don't need to do any authorization or personalization client side, you don't even need an authentication service, just the membership providers set up on the individual domain services host.

     For the impersonation thing, now that I think it through a little more, that would not work. Was remembering use of the WindowIdentity in a scenario where you did have the full creds available. If you used Windows auth instead of Forms however, I think it might work, but again have not tried that part.

  • hunsra

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by hunsra on Oct 27, 2010 22:14

    Brian, thanks again.  I think I'll have to settle for using Windows auth.  I have tried it and it does work, but I wanted to avoid using the browser to establish the login, and let the Silverlight application do it.  We'll go that way for now.

    -Randy

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Ted on Oct 28, 2010 06:52

    Thanks Brian, this is nice and useful as far as it goes.  However, while you deal with making the "Authentication Domain Service", you say nothing about where the data is actually stored.  All of the examples I have found so far that deal with these assume the data is stored in some version of MS SQL.  I have been told that if I want to use a different RDBMS, such as MySQL, I have to make a customer authentication domain service.

    Now, creating a data model using a connection I have previously created to a schema in MySQL is trivially easy.  And  have created a test schema with a table to hold user credentials (along with an additional 'nickname'), a lookup table with role names, and a third to hold the many to many relations between useers and roles.  Can you either tell me how to tell my custom authentication domain service to use it rather than look for a DB in MS SQL, or point me to a resource that shows how to do it?

    Thanks

    Ted

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Oct 28, 2010 15:34

    Ted,

    You have two choices - one is a custom authentication domain service and override ValidateUser to do your own look up wherever you like. The other that I favor is writing custom membership and role providers that do those look ups because then those can be integrated with non-RIA WCF services, ASP.NET, Client Application Services, or anywhere else membership and role providers are used. There are tons of examples of writing custom membership and role provides out there.

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by KK on Nov 10, 2010 07:51
    How's the rest of the topics coming along?  I'm eagerly waiting for "Structuring WCF RIA Services Applications".
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Marius H Enerud on Nov 18, 2010 00:05

    Hi!

    Thanks for this nice tutorial! I'm pretty new into Silverlight and I seem to have a problem that struggle to solve:

    I followed your tutorial step-by-step, but when I execute the application and push the OK-button (to run the login) I get an exception:

    Load operation failed for query 'Login'. Could not load type 'Web.CustomerMembershipProvider'.

    The exception fires here in the web.config file:

    <membership defaultProvider="myCustomProvider">
        <providers>
            <add name="myCustomProvider" type="Web.CustomMembershipProvider"/>
        </providers>
    </membership>

    I thought maybe that I should have a Namespace.ClassName naming convention, but I tried all kinds of namespaces without success...

    Do you know what could be the answer to my problem?

    Thanks,

    Marius

     

     

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Nov 18, 2010 00:23

    Looks like you modified the membership element and broke it. The one in the download code reads:

    <membership defaultProvider="myCustomProvider">
          <providers>
            <add name="myCustomProvider" type="TaskManager.Web.CustomMembershipProvider,TaskManager.Web"/>
          </providers>
        </membership>

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Marius H Enerud on Nov 18, 2010 12:06

    Thanks for your quick answer, Brian. But I'm still a bit confused about how to resolve the issue..

    If I would create my own MembershipProvider-class (based on the techniques in your text) and I would call it "CustomMembershipProvider", how do I reference it in the web.config file to avoid the exception? Are there any other elements that I need to configure to get it working?

    I forgot to mention that I'm writing this Solution in VB.

     

    thanks again,

    Marius

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Nov 18, 2010 13:17
    Hi Marius, The type property in the membership element just needs to take on the form "fully-qualified-type-name,assemblyname". So whatever your custom provider name is with its full namespace (i.e. web project name by default if you put it there, or class library project name by default if you put it there). If you put it in a class library, you will naturally also need a reference to that library to get it pulled into the \bin directory of the web app, even though there is no code in your web app that is using it, once you add it to your config the framework is going to use it in the web app. You of course could use the built in SqlMembershipProvider as well.
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Marius H Enerud on Nov 18, 2010 15:12

    Thanks for your quick answer, Brian. But I'm still a bit confused about how to resolve the issue..

    If I would create my own MembershipProvider-class (based on the techniques in your text) and I would call it "CustomMembershipProvider", how do I reference it in the web.config file to avoid the exception? Are there any other elements that I need to configure to get it working?

    I forgot to mention that I'm writing this Solution in VB.

     

    thanks again,

    Marius

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Nov 18, 2010 15:36
    The only thing particular to VB is that they hide your root namespace from you more so than C#. You have to know what your fully qualified type name is. I can't tell that without seeing your project code, but again, unless you have customized your namespaces, it is the project name that you added the class to. So if you added it to your web project and its name is MySLHost.Web, then your type name is MySLHost.Web.CustomMembershipProvider and the type attribute on your membership add eleement would be MySLHost.Web.CustomMembershipProvider,MySLHost.Web.
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Marius H Enerud on Nov 18, 2010 16:06

    Oops! Seems that I refreshed the page so that my text was posted several times... sorry!

    Thanks for your explanation, but unfortunately it didnt help me: I still receive the same exception when I try to call the Login-function. 

    Here is det exception that raises when I try to call the Login-function in the Authenication class :

    Load operation failed for query Login. Could not load type
    'RlAinterview.web.CustomMembershipProvider' from assembly
    'RlAinterview.web'. (C:\Users\marius\Documents\Visual Studio
    20 1O\Projects\RlAinterview\RlAinterview.web\web.config line 24)
    Inner exception message: Could not load type
    'RlAinterview.web.CustomtMlembershipProvider' from assembly
    'RlAinterview.Web'.

       at System.Web.Security.Membership.Initialize()
       at System.Web.Security.Membership.get_Provider()
       at System.Web.Security.Membership.ValidateUser(String username, String password)
       at System.ServiceModel.DomainServices.Server.ApplicationServices.AuthenticationBase`1.ValidateUser(String userName, String password)
       at System.ServiceModel.DomainServices.Server.ApplicationServices.AuthenticationBase`1.Login(String userName, String password, Boolean isPersistent, String customData)
       at Login(DomainService , Object[] )
       at System.ServiceModel.DomainServices.Server.ReflectionDomainServiceDescriptionProvider.ReflectionDomainOperationEntry.Invoke(DomainService domainService, Object[] parameters)
       at System.ServiceModel.DomainServices.Server.DomainOperationEntry.Invoke(DomainService domainService, Object[] parameters, Int32& totalCount)
       at System.ServiceModel.DomainServices.Server.DomainService.Query(QueryDescription queryDescription, IEnumerable`1& validationErrors, Int32& totalCount)
       at System.ServiceModel.DomainServices.Hosting.QueryProcessor.Process[TEntity](DomainService domainService, DomainOperationEntry queryOperation, Object[] parameters, ServiceQuery serviceQuery, IEnumerable`1& validationErrors, Int32& totalCount)
       at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior`1.QueryOperationInvoker.InvokeCore(Object instance, Object[] inputs, Object[]& outputs)

     

    ..and here is the code for the login-button that trigger the exception:

    Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click

        Dim loginOp As LoginOperation = WebContext.Current.Authentication.Login(TextBox1.Text, TextBox2.Text)

        AddHandler loginOp.Completed, AddressOf loginIsCompleted

    End Sub

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Marius H Enerud on Nov 18, 2010 16:10

    ...and here is the event-handler for the Login-function:

    Private

    Sub loginIsCompleted(ByVal sender As Object, ByVal e As EventArgs)

        Dim op As LoginOperation = CType(sender, LoginOperation)

        If op.HasError Then 

            ErrorWindow.CreateNew(op.Error)

            op.MarkErrorAsHandled()

            Return

        ElseIf Not op.LoginSuccess Then 

            ErrorWindow.CreateNew("Login failed...")

            Return

        Else

            MessageBox.Show("Success!")

            Return

        End If

    End Sub

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by bitdisaster on Feb 09, 2011 02:40
    In my scenario the user can request to join another role from teh client. How coud I update the roles of user when the access to the role was granted. Is their a way wihtout doing a logout/login?
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on Feb 09, 2011 16:06
    When you set up an Authentication Domain Service, it is queryable directly like any other domain service. It exposes a collection of your user type (AuthUser in my sample), which is an IPrincipal (meaning it has an IsInRole method on it). So you can do a Load operation for the GetUserQuery method on that domain context to get it to reload the user and its roles from the server side.
  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Mahdi on Feb 23, 2011 20:35

    Hi Brian,

    I created a sample of custom membership provider for a business application but i don't what is my problem that i got the below error when i want to register a new user :

    (

    Invoke operation 'CreateUser' failed. The HTTP request to 'https://localhost:52878/ClientBin/SLCustomMembershipProvider-Web-UserRegistrationService.svc/binary/CreateUser' has exceeded the allotted timeout. The time allotted to this operation may have been a portion of a longer timeout.

    )

    and you can get my porject here.

    please help to find my problems.

    Thanks a lot

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by George P. on May 05, 2011 11:34

    In your post you said that we can put what ever other information we want to AuthUser. But how are we going to update this information? Using your approach and with my limited knowledge i don't see how this can be done.

    For example if in AuthUser i have a property PhoneNumber how am i going to fill it using your approach?

    Thank you.

  • -_-

    RE: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Brian Noyes on May 08, 2011 00:52
    You can tie it in with the ASP.NET Profiles functionality if you set up a profile for the authenticated user. See this article: http://msdn.microsoft.com/en-us/library/ee707350(v=vs.91).aspx
  • hbteun

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by hbteun on Jun 09, 2011 14:53

    Hi Brian,

    do you know a good example of an (preferably a custom) AuthenticationService inside a RIA services class library for SL4?

    As I understand it, the WebContext is not created and you have to create it your self. But I get an exception when using it: The DomainContextType is null or invalid and there are no contexts generated from AuthenticationBase<T>.

    Greetings,
    Teun

  • hbteun

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by hbteun on Jun 09, 2011 16:59

    Hi Brian,

    I solved it. It was an typing error in the DomainContextType string.

    For other people who want place the authentication service in a RIA services class library check this post: Silverlight forum

    Greetings,
    Teun

  • KoenJordens

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by KoenJordens on Jul 25, 2011 15:33

    Hi Brian,
    First of all: Great article !!

    Just one question, how can I fill in the missing parts on the AuthUser class ?

    grtz, Koen.

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Jul 30, 2011 02:44

    Hi Koen

    Depends on what "missing parts" you are referring to? Do you mean adding personalization properties? If so, see my webinar here on Silverlight show on securing and personalizing Silverlight apps.

    If not, let me know what you had in mind.

    Thanks

    Brian

  • KoenJordens

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by KoenJordens on Jul 31, 2011 15:58

    Hi Brian,

    Thanks for your response.
    I watched your webinar ... nice stuff.

    In the demo solution you use the silverlight app to supply the FavoriteColor property of the User object and save the user in the asp.net database.

    My goal is to add additional fields (name, first name, ...) from my own database from within the service project.
    Is that possible ? And how would you do that ?

    Grtz, Koen.

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Jul 31, 2011 19:01

    Koen,

    You have a couple of paths you could take there. One is to write custom membership and profile providers to point to your own tables. Depending on the schema of those tables, this is straightforward and makes the providers reusable outside of RIA Services (web apps and normal WCF services can use them too). 

    The other path is to override the ValidateUser and GetAuthenticatedUser methods and do your own data access to look up the username/password and to create the instance of the user object.

    Hope that helps.

    Brian

  • sonny_lp

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by sonny_lp on Aug 11, 2011 00:27

    Hi,

    Thank you for this well written article. I was able to create my own custom membership provider as well as role provider following your article and they work well. I tried to create a custom ProfileProvider in the hope that I could add some custom properties to the user such as company, so that I could retrieve this information in my RIA service. To my disappointment, I cannot see my custom properties on the server side (in the RIA Service method). Is there anything, I am missing? Or is there any other way to achieve this?

  • koo9

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by koo9 on Sep 13, 2011 23:14
    just a crazy thought, should the host service return role base xap file base on the user permission? then again, it's too much work. it's easier with html. doing authorization on client side is not really a good idea with sl.
  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Sep 15, 2011 18:02

    With either Prism or MEF, you could conditionally load different XAP files based on role after initially loading a root app assembly to establish the security context. I wouldn't generally recommend that as it will be complicated to manage and maintain.

    I don't think you can state in general that doing authentication or authorization on the client side is not a good idea, it depends on the app, the context, the users, the deployment scenarios, etc. Certainly for OOB apps you have no choice.

  • jiang212003

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by jiang212003 on Sep 27, 2011 10:32
    excellent jobs.
  • Benoit73

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Benoit73 on Oct 17, 2011 05:49

    The login doesn't work for me. When I do a try/catch like this one:

    try{

    loginOp = WebContext.Current.Authentication.Login(UsernameTextBox.Text, PasswordTextBox.Text);

    }catch(Exception eee){

    MessageBox.Show(eee.Message);

    }

     

    I get a message like this one:

     

    The URI model <<file>> is not valid; the model <<http>> was expected.

    Parameter name: via

     

    Any clue why?

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Oct 17, 2011 06:03

    Benoit73,

    Anytime you see that <file> error message, tell yourself "I should not have blindly clicked OK in that dialog that warned me that a Silverlight client using RIA Services would not run correctly in the debugger unless the hosting web project is the startup project." :)

  • Eran

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Eran on Dec 07, 2011 02:33

    Excellent.

  • singlepoint

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by singlepoint on Feb 12, 2012 21:09

    Hi Brian

    I was following this post lately, once my domain context got created on the client side, it started giving me an error which says

    WebContextBase.User inaccessible due to it's protection level. Can you please give me some hint what I am doing wrong here. I am new to .Net. Please bear with me if it's a nonsense question.


  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Feb 13, 2012 01:11

    Hi singlepoint,

    Are you using WebContext.Current.Authentication.User to get to it or are you trying to use the property directly on the WebContext instance?

  • singlepoint

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by singlepoint on Feb 13, 2012 08:08

    Hi Brian, 

    Thanks for replying. This is the expression I am using

    WebContext.Current.User

    ain't this user supposed to be our AuthUser? But it's not accessible. 

    Thanks

  • singlepoint

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by singlepoint on Feb 13, 2012 08:10

    Brian one more thing, if I do WebContext.Current.Authentication.User then I get the user but I can't find the isAuthenticated property.

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Feb 13, 2012 17:14

    Singlepoint, I'm not sure why you are getting that error. That error is the standard one you get if you try to access a private, protected, or internal member outside of the scope where it is accessible. However, when the WebContext class gets generated on the client side, it should redeclare the User property as public as you are alluding to. In which case you should not get this error.

    First I would confirm that I have added the AuthenticationDomainService with proper definition on the server side as outlined above. Then I would double check that the WebContext class in the generated code has a redefined User property that wraps and exposes the base class one and that the property is public. Also double check that the visibility of the AuthUser class is public.

    If all those are in place, I can't think why it would give you that error.

  • cmeyerPng

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by cmeyerPng on Feb 23, 2012 02:25

    Could you please upload the sample code again? Unfortunately the zip file is empty.

    Thanks!!!

  • cmeyerPng

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by cmeyerPng on Feb 23, 2012 05:50

    Could you please upload the sample code again? Unfortunately the zip file is empty.

    Thanks!!!

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Feb 24, 2012 21:47

    cmeyerPng, you will have to try again. The zip is fine, just downloaded it to one of my machines to make sure.

  • TKelley

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by TKelley on Mar 25, 2012 18:10

    Hey Brian,

    I liked the article and learned something.  One thing that would be really useful is to show how to mix WCF Authorization, Authentication with Prism.  Perhaps in it's own module.  I bought this book and would buy the one I'm speaking about.

    Tim

     

  • anabifar

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by anabifar on Apr 09, 2012 21:19

    Hi Brian,

    I've downloaded the sample part 7 , but i can't run it and see how it works, I'm getting an error that time picker could not be found, do you have any idea???

    Thanks,

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Apr 10, 2012 18:01

    You need to have the Silverlight Toolkit installed. Sorry, should have stuck to core Silverlight controls to make the demo more portable.

  • Mivoat

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Mivoat on Apr 16, 2012 17:33

    Very useful article Brian - thank you.

    I'm new to web security, so please forgive me:

    Even if I encrypt the password at the client side before submitting it with

    WebContext.Current.Authentication.Login

    - couldn't that be picked up by someone watching the net traffic, and then impersonated?  I'm worried they could then get a list of all the web services and then play all sorts of havoc?

    - Or does the above Login routine do it's own encryption, that varies each time somehow?

    My app is not hyper-sensitive with financial transactions, etc but I'm just wondering what is considered a sensible security arrangement for most LOB apps?

    Is it considered generally secure enough as long as encryption keys are changed from time to time?  Do most hackers watch net traffic, or do they just try lots of password combinations with intelligent guesses?

    BTW My app config is nothing special, just a plain vanilla SL4 business app, deployed to Azure and using SQL Azure.

    Many thanks, Clive

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Apr 16, 2012 20:43

    Clive,

    This does presume that you are using SSL (HTTPS) for the authentication call that passes the credentials at a minimum. At that point it is no more or less secure than every web site you you log into out there. Once the authentication has happened, it uses the same session cookie based approach for maintaining the secure session that ASP.NET does, which has protections for trying to use that cookie from another machine and has timeouts to avoid having it used again from the same machine at some later time by another user. 

    So it is "secure enough" - good enough for many banking, medical, and other domains.

    Hope that helps.

    Brian

  • Mivoat

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Mivoat on Apr 17, 2012 13:59

    Brian

    Yes that does help. 

    But your (very useful) TaskManager example doesn't use https to login and so I'm wondering if its pattern is only appropriate for use inside firewalls - not really for the public internet?

    I've looked for help on using https and there are warnings that it's difficult and involves having to use IIS for testing.

    I think I may be somewhat typical - having come from the world of the MSSQL stack, with VB Forms, (and avoided what I regard as fundamentally 70s mainframe architecture - screen refreshes coming from a big cpu at the end of a wire), and now want to take advantage of this great new architecture (appropriate processing at both ends with easy data interchange).

    Bottom line - I was hoping to avoid having to become an expert in IIS and net protocols, and use a recommended pattern so I could stick mostly to data modelling etc.

    If https is recommended for the login process on a public site can you recommend a simple example to download?   Or do most public sites just heavily encrypt username and password over http during login, and then keep regular backups and hope for the best?

    Many thanks for your help, Clive

     

     

     

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Apr 17, 2012 14:16

    I only didn't use HTTPS in the sample because that requires running from IIS, setting up your certificate, etc. - stuff that is outside the scope of the article. There are plenty of tutorials for setting that up. This is completely appropriate for outside the firewall and I would always deploy with HTTPS for the authentication if not the whole site, depending on the nature of the data going back and forth.

    If you are building and deploying distributed Silverlight browser apps you are a web developer. You don't have to be an IIS expert as a web developer, but you do at least have to learn how to set up applications/virtual directories in IIS and configure an SSL cert if you want to be successful deploying for real world scenarios.



  • Mivoat

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Mivoat on Apr 17, 2012 15:22

    Thanks Brian.

    That puts it in perspective.

    Clive

  • MattHousley

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by MattHousley on May 02, 2012 16:43

    Hi Brian,
    Great set of articles, thank you.

    When I run the example project under Visual Studio it works great, but when I deploy to IIS 7, I just get a 404 for login.aspx.

    How can I configure IIS to stop this from happening?

    Thanks again

    Matt

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on May 03, 2012 14:37

    Presumably your root web.config has an authorization element with deny users="?". ASP.NET auto redirects in that case and by convention expects you to have a Login.aspx page, which this solution does not because it was not intended to show creating the secure session through a login page (which does work fine with RIA Services by the way).

    You can create one easy enough by creating a page with that name and dragging and dropping a login control onto it and you are done.

    But the real answer is - if you want clients to log in through the Silverlight app, don't restrict anonymous users from getting to the hosting page or the ClientBin directory.

  • MattHousley

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by MattHousley on May 03, 2012 16:39

    Hi Brian,
    Thanks for you reply.
    No at this point, the web.config file is exactly as it is in your TaskManagerPart7 project.

    I'm assuming that this is how to allow anonymous users to get to the hosting page and the XAP.

    I've added the following to the web.config file, but I still get the same result.:

        <authorization>
            <allow users="?"/>
        </authorization>
    </system.web>
     
    <location path="TaskManagerTestPage.aspx"><system.web><authorization><allow users="?"/></authorization></system.web></location>
    <location path="TaskManagerTestPage.html"><system.web><authorization><allow users="?"/></authorization></system.web></location>
    <location path="Silverlight.js"><system.web><authorization><allow users="?"/></authorization></system.web></location>
    <location path="ClientBin/TaskManager.xap"><system.web><authorization><allow users="?"/></authorization></system.web></location>

    In IIS, the Authentication for the Web App, has Anonymous Authentication enabled as well as Forms Authentication, with HTTP 302 Login/Redirect enabled. ASP.Net Impresonation is Disabled. That's all that appears in the Authentication list.

    Regarding the IIS Installation it's on Windows 7 Ultimate, with Request Filtering and URL Authorization enabled under Secuity for IIS in "Turn Windows features on or off".

    I've started a thread on MSDN, but I haven't found a solution there either.

    Any further help would be greatly appreciated.

    Thanks again.

    Matt

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on May 03, 2012 20:41

    Are you positive there is not a web.config in the root site directory with deny anonymous or even at the machine config level? That is the only thing I am aware of that would cause what you are describing if anonymous is allowed through IIS.

  • NikitaSherman

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by NikitaSherman on May 10, 2012 23:11

    Thanks, great articale!

  • MattHousley

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by MattHousley on May 15, 2012 15:28

    Hi,

    I solved the '404 on the login.aspx' problem by changing the connection credentials in the Application Settings. The Web Application was set to use "Application user (pass-through authentication)" [see "Connect As" in the Edit Application dialog]. Once this was changed to a "Specific user", all was well.

    Hope that helps anyone with the same problem.

    Matt

  • psaxton2012

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by psaxton2012 on Jul 29, 2012 21:43

    Hi Brian

    For the user provider if we have custom encryption for passwords is there any way of hiding this within the client?

    I am assuming I need to encrypt the password entered by the user on the client before sending it to the client?

    Paul

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Jul 30, 2012 01:53

    RIA Services treats the password as a plain text password that you should be sending over SSL for protection. As long as whatever you do on the client and server sides is symmetric, should not matter to RIA Services as long as you are using a custom provider.

  • Paritosh8889

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Paritosh8889 on Sep 24, 2012 15:36

    Hi Brian,

    First of all thanks for providing such great articles to us. I am new in silverlight and want to secure my Application and was looking for the code as u did it here.

    i just wanted to know if my login happens from serverside i.e. aspx page then how to load my webcontext or how my custom Authentication services calls happen?    

     

    Thanks for your time....    

  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Sep 24, 2012 15:46

    You just need to set up the WebContext with the right authentication scheme (Windows or Forms) as described in the article, then just call LoadUser and it will populate the context based on the existing ASP.NET secure session.

  • Paritosh8889

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Paritosh8889 on Sep 25, 2012 10:08

    Hi Brian,

    Thanks or your suggestions i was doing similar to this, but in my existing application while i have implemented the same code it was not calling my role provider an membership provider classes.

    can you help me in this? also can we change the message which we get after calling domain services with unAuthorized user role?

    FYI, while i have made demo for this it was working Fantastic. but implementing in new it is not calling my custom provider, i have checked my web.config also.

     

    Thanks again.    

  • Paritosh8889

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Paritosh8889 on Sep 25, 2012 10:35
    Also i am using my domain services and entity model from other project an i am coniguring my web.config in the main project WEB portion. other thing is my login is happens from other website.
  • brian.noyes

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by brian.noyes on Sep 27, 2012 02:02

    While you can definitely put your data-centric domain services in a separate library, I have never been successful doing that with the AuthenticationDomainService - it needs to go in your web hosting project. I'm not sure why that is, but the consequence of not putting it there is that the right stuff does not seem to get generated on the client side. 

    As far as customizing the messages that go back and forth you are out of luck there. That part was not built extensible as far as I know. The closest you can come is to add properties to the user class that get passed back after authentication is complete, but in terms of passing custom parameters down with the message, there is nothing built in to WCF RIA Services to accomodate that. However, this is all riding on WCF under the covers, so if you can learn some ninja WCF skills, you can write a custom client interceptor that could tack on additional headers and some server side interception that would strip them off. I am expert level with WCF myself and teach our WCF Master Class, but that is something that I know the pipeline is capable of but would have to spend a ton of time trying to figure out how to get it all tied in, so not a recommended path for the mere mortal programmer.

  • Paritosh8889

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by Paritosh8889 on Sep 28, 2012 14:13

    Thanks brian for the important information....

    Also Thanks for writing such a nice articles... :)

  • sirajnm

    Re: WCF RIA Services Part 7 - Authentication and Authorization


    posted by sirajnm on Oct 22, 2012 17:51

    Dear

    How to get the user specific information stored in the database (eg: FriendlyName) from the r User base class. 

    Thanks

    Siraj

Add Comment

Login to comment:
  *      *       

From this series