Using LoginView on HyperLinkFields within a GridView

Posted by Ryan Baxter Wed, 13 Aug 2008 19:45:00 GMT

The title of this post is a bit misleading. Using a LoginView to manage the security of HyperLinkFields within a GridView does not work. There are, however, other means to achieve the same result.

Using the GridView’s OnRowDataBound event, I’ve set my Cells containing HyperLinkFields, on DataRows with a RowIndex of -1, to an empty string if the user does not belong to the “Administrators” role. This hides my HyperLinkFields from underprivileged users and prevents elements of my GridView’s header and footer from not appearing.

protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowIndex != -1)
    {
        if (!Page.User.IsInRole("Administrators"))        
            e.Row.Cells[0].Text = String.Empty;
    }           
}

*Update

I just found a thread on the ASP.NET forums that covers the same problem. In their solution, the GridView’s RowType is checked before setting the Cell’s Visibility property to false. This makes more sense than relying on the RowIndex property to determine whether or not a DataRow’s Cell should be hidden. In the method below, I’ve integrated the DataControlRowType enumeration as suggested by the ASP.NET forums. Since setting the Visibility property of Cells containing HyperLinkFields caused my GridView headings to not line up properly, I decided to assign the Cell’s Text property to String.Empty as in my previous example.

protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{                  
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (!Page.User.IsInRole("Administrators"))
            e.Row.Cells[0].Text = String.Empty;
    }   
}

IE7's Inanimate GIF

Posted by Ryan Baxter Wed, 11 Jun 2008 12:06:00 GMT

Animated GIFs are most often used as activity indicators in modern AJAX (asynchronous JavaScript and XML) enabled websites. I decided to use a GIF (Graphic Interchange Format) from ajaxload.info on an application that I’ve been developing at work. The application performs server-side processing on files uploaded by employees. Processing time varies depending on the size of the file. Larger files take longer.

I wanted the animated GIF to appear when the file upload button was clicked so I placed the image within a DIV tag and hid it by setting a blank CSS display property. OnClick of the upload button, a JavaScript function toggled the display value to “block”, making the DIV appear. This worked as expected in Firefox and IE6, but not in IE7. The DIV appeared in IE7, but it’s GIF wasn’t moving.

A little googling turned up a helpful comment on Rick Strahl’s blog.

I’ve run into a problem with animated gifs inside of a hidden area of a Web page that is hidden with style.display=’none’. When the area is made visible again, in Internet Explorer this causes the image to not be displayed an animated GIF whatever I try. [sic]

Apparently IE7 doesn’t like to animate hidden GIFs. User submitted comments on Rick Strahl’s blog provided many solutions, but only a couple worked in my situation. The first uses the JavaScript setTimeout method to populate the image’s SRC attribute 200 ms after the function call. The second sets the DIV’s innerHTML to a string containing an IMG tag with the animated GIF.

<script language='javascript'> 
    function ShowLoading(elementId) 
    {
        document.getElementById(elementId).style.display = "block"; 
        setTimeout('document.images["loadingImage"].src = "../images/loading.gif"', 200); 
    } 
</script>

Neither solution is ideal, but setting the element’s innerHTML felt a little bit cleaner to me.

<script language='javascript'>
    function ShowLoading(elementId)
    {   
        var element = document.getElementById(elementId);    

        element.innerHTML = "<img src='../images/loading.gif'>";    
        element.style.display = "block";
    }
</script>

*IE7 may have animations disabled. Go to Tools > Internet Options > Advanced > Multimedia. Checking “Play animations in webpages” may affect how IE7 renders your animated GIFs.

Temporary Identity Impersonation in ASP.NET

Posted by Ryan Baxter Tue, 27 May 2008 16:01:00 GMT

Uploading files in an ASP.NET application is relatively easy to do. Uploading to a remote machine is a little bit trickier, but certainly doable. I followed a set of instructions on aspalliance.com, but rather than declare an account to impersonate in my web.config file, I decided to do it in code. That way I could use impersonation only when needed and encapsulate it for later use.

I referred to an article on Microsoft’s Help and Support website about how to implement impersonation. Their code worked great, but I decided to put it in a class to help keep things DRY.

using System;
using System.Web;
using System.Web.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace Utilities
{    
    public class ImpersonateUser
    {
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_PROVIDER_DEFAULT = 0;

        WindowsImpersonationContext impersonationContext;

        [DllImport("advapi32.dll")]
        public static extern int LogonUserA(String lpszUserName,
            String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public bool ImpersonateValidUser(String userName, String domain, String password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;
        }

        public void UndoImpersonation()
        {
            impersonationContext.Undo();
        }
    }
}

After referencing my Utilities namespace I was then able to impersonate the account required for uploading:

if (FileUpload1.HasFile)
{
    ImpersonateUser impersonateUser = new ImpersonateUser();

    if (impersonateUser.ImpersonateValidUser("userName", "", "password"))
    {
        FileUpload1.SaveAs(Server.MapPath("~/files/fileName.txt"));
        impersonateUser.UndoImpersonation();
    }
    else
    {
        throw new Exception("Identity impersonation has failed.");
    }   
}

*The SaveAs method of the FileUpload control requires a root path. Using Server.MapPath will provide the root path of your IIS virtual folder.

Older posts: 1 2 3