locked
Impersonate user by override ServerApplicationContext? Possible? Another way around? RRS feed

  • Question

  • Is there any way to impersonate a user in LightSwitch HTML? 

    Today I am calling a Web API and getting user info by using the following code: 

    using (ServerApplicationContext ctx = ServerApplicationContext.Current ?? ServerApplicationContext.CreateContext())
          {
            var currentUser = ctx.Application.User;
           }

    Is there any way of override the user with another user? 


    • Edited by Phero_ Wednesday, September 21, 2016 8:16 AM
    Wednesday, September 21, 2016 8:10 AM

All replies

  • From great Dale Morrison examples I use this code:

    Public Function GetAppSecurityObjects() As Dictionary(Of String, Object)
    
                Dim appSecurityInfo As New Dictionary(Of String, Object)
    
                Using ctx As ServerApplicationContext = If(ServerApplicationContext.Current, ServerApplicationContext.CreateContext)
    
                    Dim currentUser = ctx.Application.User
                    Dim removeAdminPermission As Boolean = False
                    If currentUser.IsAuthenticated Then
                        'Temporarily raise permissions
                        If Not currentUser.HasPermission(Permissions.SecurityAdministration) Then
                            removeAdminPermission = True
                            currentUser.AddPermissions(Permissions.SecurityAdministration)
                        End If
    
                        'Get all the roles for this app
                        Dim roleList = (From role As Microsoft.LightSwitch.Security.Role In ctx.DataWorkspace.SecurityData.Roles
                                        Select role.Name).Execute.ToList
    
                        'Now get all the permissions for the app
                        Dim permissionList = ctx.DataWorkspace.SecurityData.Permissions.GetQuery().Execute().Select(Function(x) x.Id.Split(":")(1)).ToList()
    
                        'Don't forget to drop permission if necessary
                        If removeAdminPermission Then currentUser.RemovePermissions(Permissions.SecurityAdministration)
    
                        appSecurityInfo.Add("Roles", roleList)
                        appSecurityInfo.Add("Permissions", permissionList)
                    End If
    
                End Using
                Return appSecurityInfo
    
            End Function

    Sorry for VB.Net, HTH


    Marco

    Wednesday, September 21, 2016 3:30 PM
  • This is REALLY hacky. In my case I wanted to have a DesktopClient that had forms authentication and a HTMLClient that ran as a "guest" user. 

    In the Global.asax, add the following crappy code:

    		protected void Application_AuthorizeRequest(object sender, EventArgs e)
    		{
    			if (Request.Path == "/")
    			{
    				LoginAsGuest();
    				Response.Redirect("~/htmlclient/", true);
    			}
    			else if(string.Compare(Request.Path, "/description.html", StringComparison.InvariantCultureIgnoreCase) == 0)
    			{
    				LoginAsGuest();
    			}
    			else if (string.Compare(Request.Path, "/privacypolicy.html", StringComparison.InvariantCultureIgnoreCase) == 0)
    			{
    				LoginAsGuest();
    			}
    			else if (string.Compare(Request.Path, "/htmlclient/", StringComparison.InvariantCultureIgnoreCase) == 0)
    			{
    				if (LoginAsGuest())
    					Context.RewritePath("/htmlclient/default.htm");
    			}
    			else if (string.Compare(Request.Path, "/administration/", StringComparison.InvariantCultureIgnoreCase) == 0)
    			{
    				if (Context.User != null && string.IsNullOrEmpty(Context.User.Identity.Name))
    				{
    					var returnUrl = Server.UrlEncode(Request.Url.PathAndQuery);
    					Response.Redirect("~/login.aspx?ReturnURL=" + returnUrl);
    				}
    				else
    				{
    					Context.RewritePath("/administration/default.htm");
    				}
    			}
    		}
    
    		private bool LoginAsGuest()
    		{
    			if ((Context.User == null) || (Context.User != null && string.IsNullOrEmpty(Context.User.Identity.Name)))
    			{
    				using (var authService = new AuthenticationService())
    				{
    					var user = authService.Login("guest", "guest$1234", true, null);
    					if (user == null)
    					{
    						var returnUrl = Server.UrlEncode(Request.Url.PathAndQuery);
    						Response.Redirect("~/login.aspx?ReturnURL=" + returnUrl);
    						return false;
    					}
    				};
    
    				Context.User = new GenericPrincipal(new GenericIdentity("guest"), System.Web.Security.Roles.GetRolesForUser("guest"));
    			}
    
    			return true;
    		}
    Note that there are conditional statements for the privacypolicy and description that you would not have in your app. I left them in to show how other content items could be allowed. 


    • Edited by Ian E Wednesday, September 21, 2016 4:09 PM
    Wednesday, September 21, 2016 4:06 PM
  • I think it is a clever solution to a common problem.  +1
    Wednesday, September 21, 2016 8:17 PM
  • Good solution., but I am not using Forms - only Windows Authenfication. 
    Wednesday, October 5, 2016 9:20 AM
  • The basic concept should work with Windows Auth but you will have to rework the exception logic.   You will just do the login using a guest domain user like:

    var user = authService.Login("domain\guest", "guest$1234", true, null);

    The Response.Redirects can likely be left if the Login.aspx is available with Windows Auth, but should likely be changed to something like:

    throw new HttpException(401, "Not authorized");

    Wednesday, October 5, 2016 4:27 PM
  • Do you have any example how to configure this. I am receiving "Request is not available in this context"
    Thursday, October 6, 2016 9:50 AM