Tuesday, December 23, 2008

Authentication/Login based ArcGIS ADF Task


How do you use the ArcGIS Server .net ADF Task Framework to create a Task which will take into account whether an user is authenticated or logged in? Easy. Basically, we can extend any ADF task or override the Render method to render only when logged in. We use a session variable to indicate if user is logged in. The benefits of this is that we can use any type of login mechanism, asp.net's login control, or anything else, as long as we set a session variable to indicate login status when the user is logged in. If we use asp.net's login control, we can set an eventHandler for loggedIn event to set the session variable. The code below extends the out of the box SearchAttributesTask from the ADF so that it renders only when our user is logged in. Now note that this customTask is not a full blown task, it is just a class that extends an existing task, as simple as that.
Imports Microsoft.VisualBasic
Imports ESRI.ArcGIS.ADF.Tasks
Imports log4net
Imports ESRI.ArcGIS.ADF.Web.UI.WebControls

Namespace WebMapApp
    Public Class LoginBasedSearchAttributesTask
        Inherits SearchAttributesTask

        Private Shared ReadOnly logger As ILog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)


        Public Overrides Sub ExecuteTask()
            MyBase.ExecuteTask()
        End Sub

        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
        End Sub

        Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

            Dim Session As HttpSessionState = HttpContext.Current.Session
            Dim isRenderObj As Object = Session("loggedInSuccess")
            If (isRenderObj IsNot Nothing) Then
                Dim isRender As Boolean = CType(isRenderObj, Boolean)
                If (isRender) Then
                    MyBase.Render(writer)
                Else
                    writer.RenderBeginTag("div")
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "red")
                    writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt")
                    writer.Write("You are required to login to use this task, to login go to the CIP menu and then Login")
                    writer.RenderEndTag()
                    Return
                End If
            End If

        End Sub

    End Class
End Namespace

There's one more thing left, we need to write the declarative code inside default.aspx for this CustomTask. We should note that the Render() method is called during partial page postbacks or full postbacks, and not during callbacks. So this approach won't work without a asp.net ajax ScriptManager (e.g. in ADF9.2 apps). We wrap our task inside an ajax:UpdatePanel, and then put that ajax:UpdatePanel inside another esri:FloatingPanel. Note, that the updateMode is set to conditional for efficiency reasons, minimizing http response from the server on every postback. Because of this we need to manually update the UpdatePanel, so when the user logins, the codebehind page should call SearchCIPUP.update(), so that this task is re-rendered. Because our custom task is inside another FloatingPanel, we should remember to disable the visual elements, e.g. titlebar, closebutton, borders etc of the inner-task, as shown below.
        
        
            
                
                    
                        
                    
                                
            
        
    

The CSS code:
        .SearchCIPTaskTitleBarCSS
        {
         display:none;
         visibility:hidden;
         width:0px;
         height:0px;
        }
        .SearchCIPTaskCSS
        {
         height:100%;
         width:100%;
         border: none 0px transparent;
         position: relative;
         background-color:White;
        }
There you go, it's as simple as that. It works beautifully.

No comments:

Post a Comment