locked
How to reference Security Entities using a WCF RIA Service RRS feed

  • Question

  • Hi,

    I read Matt Thalman's approach to this task but the article is too outdated (back in the LS early days), that I couldn't even find the Microsoft.LightSwitch.dll assembly. I know the process of creating a WCF RIA Service has quite changed.

    I have created WCF RIA Services in VS2013 using Michael Washington's tutorial, but I wonder if someone has done it to access the Security Data, instead of Application Data. Particularly, I only need to retrieve the Usernames and User full names from UserRegistration.

    So far I created the Domain Service and the public class I need, but when it comes to the Context, needed for the queries to access the mentioned SecurityData, there is no such thing as LightSwitch.Implementation.SecurityData.

    Also, using Microsoft.LightSwitch is not available, therefore I can't create a ServerApplicationContext either.

    Does any of the above make any sense?

    Nicolás.

    Friday, June 27, 2014 12:33 AM

All replies

  • This RIA Service in the server project somewhat works.  I'm sure some of this code comes from a post or blog but I don't recall exactly (it's been a while).  There are some issues with this.  I'm sure I'm not using ServerApplicationContext the right way, but maybe this will give you some ideas.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    using System.Data.EntityClient;
    using Microsoft.LightSwitch.Server;
    using Microsoft.LightSwitch.Security.Server;
    using Microsoft.LightSwitch;
    using System.ServiceModel.DomainServices.Server;
    using System.Runtime.Serialization;
    
    namespace LightSwitchApplication.RIA
    {
        public class RIAService : DomainService
        {
            public static ServerApplicationContext GetServerContext()
            {
                ServerApplicationContext Context = LightSwitchApplication.ServerApplicationContext.Current;
                if (Context == null)
                {
                    Context = LightSwitchApplication.ServerApplicationContext.CreateContext();
                }
                return Context;
            }
    
            protected override int Count<T>(IQueryable<T> query)
            {
                return query.Count();
            }
    
            [Query(IsDefault = true)]
            public IQueryable<RIAPerm> GetRIAPerms()
            {
                var colPerms = from p in GetServerContext().DataWorkspace.SecurityData.Permissions.GetQuery().Execute()
                                   select new RIAPerm
                                   {
                                       Id = p.Id,
                                       Permission = p.Name
                                   };
                return colPerms.AsQueryable();
            }
    
            [Query]
            public IQueryable<RIAPerm> GetUserPerms()
            {
                string user = GetServerContext().Application.User.Name;
                var colUserPerms = from p in GetServerContext().DataWorkspace.SecurityData.Permissions.GetQuery().Execute()
                                   where p.RolePermissions.Any(x => x.Role.RoleAssignments.Any(y => y.User.UserName == user))
                                   select new RIAPerm
                                   {
                                       Id = p.Id,
                                       Permission = p.Name
                                   };
                return colUserPerms.AsQueryable();
            }
        }
    
        //public class RIAUsers
        //{
        //    public int Id { get; set; }
        //    public string UserName { get; set; }
        //    public string UserFullName { get; set; }
        //}
    
        public class RIAPerm
        {
            [Key]
            public string Id { get; set; }
            public string Permission { get; set; }
        }
    }

    Friday, June 27, 2014 1:55 AM
  • This RIA Service in the server project somewhat works.  I'm sure some of this code comes from a post or blog but I don't recall exactly (it's been a while).  There are some issues with this.  I'm sure I'm not using ServerApplicationContext the right way, but maybe this will give you some ideas.

    Hessc,

    I'll try it tomorrow, thanks. So if not creating the RIA Svc as a separate Project (Class Library), I should add this to the Server Project as what, a regular user class?

    Also, do you recall what the issues are/were?

    Outside the Server Project, I couldn't add the using Microsoft.LightSwitch.x because I am missing an assembly reference, and I don't know which one is it. Doing a search of LightSwitch in the Add reference dialog returns nothing.

    thx.

    Friday, June 27, 2014 2:55 AM
  • Yes, just add a class to the server project.

    The code works but there are better ways to use ServerApplicationContext, so that it is properly disposed.  Here is probably the best thread on the topic.  Also, this RIA service is not fully featured.  It allows you to see the available permissions in the HTML client but not administer roles or assign them etc.  It would not be too difficult to add the same functionality as the Silverlight client.  I was fooling around with this a while back but got sidetracked.  My apps normally include both clients so there was not an immediate need to access security data in the HTML client.  This is changing now though so I will soon need it. 

    Friday, June 27, 2014 3:44 AM
  • Hi,

    I'd strongly suggest you check this out. Its an entire article on a 'core' LS HTML project.

    With emphasis on security, section 6 of that blog post will help you a LOT!

    The post is written by Dale Morrison, a shining light in the LS community!


    Ian Mac

    Friday, June 27, 2014 12:56 PM
  • Hi,

    I'd strongly suggest you check this out. Its an entire article on a 'core' LS HTML project.

    With emphasis on security, section 6 of that blog post will help you a LOT!

    The post is written by Dale Morrison, a shining light in the LS community!


    Ian Mac


    Thanks Ian, I am aware of that. I follow Dale and his work. However I've been working on this Project for almost a year and I'm not sure if it's possible to adapt it to Dale's core solution. I would definitely consider it for my next one. AND section 6 is very interesting, thanks.
    Friday, June 27, 2014 1:29 PM
  • Hello again,

    Well, I created a SecurityDataService class and added it to the Server Project, inside a folder called UserCode.

    It uses Jan's approach to appropiately dispose the ServerApplicationContext, if needed.

    Build. No errors. Everything looks fine. Now, the silly questionWhy I'm not seeing it when adding a new WCF RIA Service data source? It just doesn't show. I'm guessing because it is not a different Project. But I need it as a new data source.

    Here's the code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    using System.Data.EntityClient;
    using Microsoft.LightSwitch.Server;
    using Microsoft.LightSwitch.Security.Server;
    using Microsoft.LightSwitch;
    using System.ServiceModel.DomainServices.Server;
    using System.Runtime.Serialization;
    
    namespace LightSwitchApplication.UserCode
    {
        public class SecurityDataService : DomainService
        {
            public class UserRegistration
            {
                [Key]
                public string UserName { get; set; }
                public string FullName { get; set; }
            }
    
            [Query(IsDefault = true)]
            public IQueryable<UserRegistration> GetUsers()
            {
                ServerApplicationContext ctx;
                using (ServerApplicationContextProvider.GetCurrentOrNewApplicationContext(out ctx))
                {
                    var colUserReg = from u in ctx.DataWorkspace.SecurityData.UserRegistrations.GetQuery().Execute()
                                   select new UserRegistration
                                   {
                                       UserName = u.UserName,
                                       FullName = u.FullName
                                   };
                    return colUserReg.AsQueryable();
                }
            }
            protected override int Count<T>(IQueryable<T> query)
            {
                return query.Count();
            }
        }
    
        public static class ServerApplicationContextProvider
        {
            public static IDisposable GetCurrentOrNewApplicationContext(out ServerApplicationContext applicationContext)
            {
                applicationContext = ServerApplicationContext.Current;
                if (applicationContext != null)
                {
                    return new NoopDisposer();
                }
                else
                {
                    applicationContext = ServerApplicationContext.CreateContext();
                    return applicationContext;
                }
            }
            private class NoopDisposer : IDisposable
            {
                public void Dispose()
                {
                }
            }
            
        }
    
    }




    Friday, June 27, 2014 2:17 PM
  • In the server project, add a reference to ApplicationServer.dll found in the server project debug bin.  It should show up.
    Friday, June 27, 2014 2:33 PM
  • Thanks Ian.  Dale's blog is a great resource indeed.  I forgot about using the OData service to access security data.
    Friday, June 27, 2014 2:36 PM
  • In the server project, add a reference to ApplicationServer.dll found in the server project debug bin.  It should show up.

    Hessc, I did that, and it didn't show up. Plus I have 20350 warnings of conflicts between types.

    I could try 2 things: Going back to the "external" Project, and add a reference to Microsoft.LightSwitch.dll and Microsoft.LightSwitch.Server.dll (located where?) and see if I can use the ServerAplicationContext and access the SecurityData,

    or

    try the OData Service.


    Friday, June 27, 2014 3:01 PM
  • Did you by chance migrate this project from VS2012 to VS2013?  I had the same problem with my migrated app (drives me crazy). 

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/ca85b152-030c-4dfb-8319-1fafe0c920b3/vs2013-ria-service-problem?forum=lightswitch

    The example I gave you works in a clean VS2013 project on my machine.  In my migrated app I have to use traditional RIA service per Michael Washington, but of course I have not tried to get security data from that setup (although I believe it should be possible).

    • Edited by Hessc Friday, June 27, 2014 3:43 PM
    Friday, June 27, 2014 3:40 PM
  • Did you by chance migrate this project from VS2012 to VS2013?  I had the same problem with my migrated app (drives me crazy). 

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/ca85b152-030c-4dfb-8319-1fafe0c920b3/vs2013-ria-service-problem?forum=lightswitch

    The example I gave you works in a clean VS2013 project on my machine.  In my migrated app I have to use traditional RIA service per Michael Washington, but of course I have not tried to get security data from that setup (although I believe it should be possible).


    Yes, it was migrated from VS2012 to 2013...
    Friday, June 27, 2014 5:24 PM
  • I was able to repro the error 30000 warnings in the clean project.  It happened after I made some changes to the RIA service.  Here is what I did to fix it:

    1. Run VS as administrator

    2. Remove the reference to ApplicationServer.dll

    3. Delete the RIA datasource and any screens based on it

    4. Rebuild solution

    5. Add datasource > RIA Service > Add reference to the ApplicationServer.dll again

    6. the RIA Service and entities show up, selected them

    7. Rebuild solution

    Everything works.  Again this is on the clean VS2013 project.  I still can't get the migrated project to accept a RIA service based on ServerApplicationContext inside the server project.

    Friday, June 27, 2014 7:38 PM
  • I appreciate your effort, Hessc.

    I tried adding a reference to Microsoft.LightSwitch, Microsoft.LightSwitch.Server to the original WCF RIA Service, and couldn't refer to ServerApplicationContext, because it belongs to the LightSwitchApplication class.

    So I decided to try adding a reference to the Application.Server.dll as you pointed out, and surprisingly the errors dissapeared. After rebuilding all, I managed to add the WCF RIA SecurityData Service as a new data source, and created a grid with the UserRegistrations. When I started the application in debug mode, all sorts of errors emerged, so I decided to undo all changes and discard this approach.

    I'm frustrated, I know, because I thought "I had it", but it's not a must have feature, not right now.

    Friday, June 27, 2014 9:00 PM
  • Sorry you're having trouble.  I had plenty of trouble with this approach myself.  I think when I get back to it, I am going to try using webApi and calling it javascript from the html client.  Seems to be cleaner than this RIA implementation.
    Saturday, June 28, 2014 4:08 AM
  • Thanks Ian.  Dale's blog is a great resource indeed.  I forgot about using the OData service to access security data.

    I used Dale's code to create this:

    Allow LightSwitch Users To Self-Register and Change Passwords Using MVC


    Unleash the Power - Get the LightSwitch HTML Client book

    http://LightSwitchHelpWebsite.com

    Saturday, June 28, 2014 12:11 PM
  • Thanks Ian.  Dale's blog is a great resource indeed.  I forgot about using the OData service to access security data.

    I used Dale's code to create this:

    Allow LightSwitch Users To Self-Register and Change Passwords Using MVC


    Unleash the Power - Get the LightSwitch HTML Client book

    http://LightSwitchHelpWebsite.com


    Sorry Angie Xu, that is not an answer to the question.
    Monday, July 7, 2014 1:35 PM