Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Integrating CAS Proxying with Forms Authentication in ASP.Net 2.0

To set up CAS authentication in ASP.Net is a relatively simple process if you don't implement Forms Authentication and do NOT require your application to act as a CAS proxy.
However, when you do want to make use of ASP.Net's Forms Authentication AND CAS-enable your application for proxying, the process is a little more involved.
The good news is that it still does not require much coding at all. It just requires a little knowledge about how CAS works and how you can get ASP.Net Forms Authentication to synchronize with it.

The source code needed for this article can be downloaded here and can be compiled in Visual Studio 2005 or greater. It will create a .Net assembly (DLL) to drop in your project's bin folder.

First compile the attached code into a .Net assembly and drop it into your project's bin folder. Then, In Web.config, make the following changes:

...


<!--Authentication mode configuration -->
<authentication mode="Forms">
    <forms name="casAuth" defaultUrl="Default.aspx" loginUrl="Login.aspx" />
</authentication>

...


<!-- Authorization configuration -->
<authorization>
  <deny users="?"/>
</authorization>

...


<!-- Pages configuration, Globally Import the CAS.Web.Security namespace so it can be used throughout your CAS application -->
<pages>
  <namespaces>
    <add namespace="CAS.Web.Security"/>
  </namespaces>
</pages>

...

Integrating CAS Proxying with Forms Authentication in ASP.Net 2.0

To set up CAS authentication in ASP.Net is a relatively simple process if you don't implement Forms Authentication and do NOT require your application to act as a CAS proxy.
However, when you do want to make use of ASP.Net's Forms Authentication AND CAS-enable your application for proxying, the process is a little more involved.
The good news is that it still does not require much coding at all. It just requires a little knowledge about how CAS works and how you can get ASP.Net Forms Authentication to synchronize with it.

The .Net assembly (DLL) and source code needed for this article can be downloaded here. Just drop it in your project's bin folder.

For an example of how to do CAS proxying with classic ASP, see me other article CAS Proxying with Classic ASP

First drop the CASAuthentication.dll (attached) into your project's bin folder. Then, In Web.config, make the following changes:

  1. Turn on Forms Authentication:
    Code Block
    xml
    xml
    
    <!--Authentication 

...

  1. mode configuration -->
    

...

  1. <authentication mode="Forms">
        

...

  1. <forms 

...

  1. name="

...

  1. casAuth" 

...

  1. defaultUrl="Default.aspx" loginUrl="Login.aspx" />
    </authentication>
    
  2. Deny all unauthenticated users
    Code Block
    xml
    xml
    
    

...

  1. <!-- Authorization configuration -->
    <authorization>
     

...

  1.  

...

  1. <deny users="?"/>
    </

...


<customErrors mode="On" defaultRedirect="MyErrorPage.aspx">
  <error statusCode="403" redirect="NoAccess.htm"/>
  <error statusCode="404" redirect="FileNotFound.htm"/>
</ customErrors>

...

VB.Net Code Examples

Default.aspx (The CAS proxier) - Your main default page

...

  1. authorization>
    
  2. Include the CAS.Web.Security namespace in your pages section.
    Code Block
    xml
    xml
    
    <!-- Pages configuration, Globally Import the CAS.Web.Security namespace so it can be used throughout your CAS application -->
    <pages>
      <namespaces>
        <add namespace="CAS.Web.Security"/>
      </namespaces>
    </pages>
    
  3. Add the CAS host url to the appSettings section. You must name the key: CASURL
    Code Block
    xml
    xml
    
    <!-- Application settings configuration -->
      <appSettings>
        <!---change CAS Url accordingly-->
        <add key="CASURL" value="https://auth.berkeley.edu/cas"/>
      </appSettings>
    
  4. Add an httpModules section with the following module. It must be inside the system.web section of your web.config file.
    Code Block
    xml
    xml
    
    <httpModules>
      <add name="CASAuthenticationV2" type="CAS.Web.Security.CASAuthenticationV2, CASAuthentication"/>
    </httpModules >
    
  5. (Optional) If you want all CASAuthentication class related errors routed to your own error page, simply add a customErrors page section to your system.web section. Mode must be set to On for the errors to be re-directed. If mode is Off or the customErrors section is not present in web.config, all errors will be written out to the current application page.
    Code Block
    xml
    xml
    
    <customErrors mode="On" defaultRedirect="MyErrorPage.aspx">
      <error statusCode="403" redirect="NoAccess.htm"/>
      <error statusCode="404" redirect="FileNotFound.htm"/>
    </ customErrors>
    
    In this example, the page MyErrorPage.aspx can access the last error reported by calling the CASAuthentication.LastError property of the CASAuthentication class.

...

VB.Net Code Examples

The CAS proxier - (Your main default page)

Panel
borderColor#cccccc
bgColor#ffffff
titleBGColor#eeeeee
borderStyledashed
titleDefault.aspx


Span
stylebackground-color:yellow
idhl
<%

@ Page Language="VB"

Span
stylebackground-color:yellow
idhl
%>


<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        If User.Identity.IsAuthenticated Then
            If Not String.IsNullOrEmpty(CASAuthentication.ProxyAppResponse) Then
                Response.Write(String.Concat("Proxied App Response: ", CASAuthentication.ProxyAppResponse))
            EndIf
        End If
    End Sub

    Protected Sub btnRunTest_Click(ByVal sender As Object,ByVal e As System.EventArgs)
            'First, let's add some proxy arguments to send to the CAS proxy
            CASAuthentication.AddProxyArgument("arg1", "hello")
            CASAuthentication.AddProxyArgument("arg2", "world")

            If Not CASAuthentication.InvokeCASProxy(ProxyAppUrl:="{url_to_your_CAS_Proxy_

Application>

Application}",

_

_
                pgtUrl:="

<secure

{secure_url_to_your_CAS_Callback_Url_

Application>

Application}",

_

_
                HttpMethodPost:=

False)

Then

Then
                Response.Write(CASAuthentication.LastError)

Return EndIf End Sub </script> <html> <head> <title>Test calling a CAS Proxy</title> </head> <body> <p><a


                Return
            EndIf
    End Sub
</script>

<html>
<head>
    <title>Test calling a CAS Proxy</title>
</head>
<body>
    <p><a href="LogOut.aspx"

>Log

>Log out

of

CAS</a></p> <p><asp:Button

CAS</a></p>
    <p><asp:Button ID="btnRunTest"

runat="server"

OnClick="btnRunTest_Click"

Text="Call

Test

Proxy"

/></

p>

p>
</

body>

body>
</

html>

...

html>

The CAS callback Url (This would be the same application page specified in the pgtUrl attribute in the call to InvokeCASProxy method shown above) - This assumes that your main application (the CAS proxier) and callback Url are part of the same application so that they can share application specific variables. If the callback Url is NOT part of the same application, then you must handle storing/retrieving the pgtIou/pgtId pair yourself. (e.g. store them in an external database).

Info
titleIMPORTANT NOTE

Because your callback Url will be called by CAS directly, you must turn off Forms Authentication for this page. This is easily achieved by adding the following to your web.config file root configuration section:

Code Block
xml
xml
<location path="ProxyCallback.aspx">
  <system.web>
    <authorization>
      <allow users="*"/>
    </authorization>
  </system.web>
</location>
Code Block
htmlhtml

<%@ PageLanguage="VB"%>

<script system.web>
</location>
Panel
borderColor#cccccc
bgColor#ffffff
titleBGColor#eeeeee
borderStyledashed
titleProxyCallback.aspx


Span
stylebackground-color:yellow
idhl
<%

@ Page Language="VB"

Span
stylebackground-color:yellow
idhl
%>


<script runat="server">


    Protected

Sub

Page_Load(ByVal

sender

As

Object,

ByVal

e

As

System.EventArgs)


        Dim

pgtIou

As

String

=

Request.QueryString.Get("pgtIou")


        Dim

pgtId

As

String

=

Request.QueryString.Get("pgtId")

If Not

       
        If Not String.IsNullOrEmpty(pgtIou)

And

_
            Not

String.IsNullOrEmpty(pgtId)

Then

Then

            'We

have

a

pgtIou/pgtId

pair

sent

from

CAS

server

server
            'Now

call

the

AssignPgtIDForCallingProxy

method

of

the

CASAuthentication

class

class
            'this

will

store

the

pgtId

in

an

application

variable

with

it's

name

the

value

of

the

pgtIou CASAuthentication

pgtIou
           CASAuthentication.AssignPgtIDForCallingProxy(pgtIou,

pgtId)

Else


        Else
            Response.Write("No

pgtIou/pgtId

pair

\

!")


        End

If

    

    End

Sub

</script> <html> <head> <title>Proxy Callback Url Page</title> </head> <body> </body> </html>

CASProxy.aspx - The CAS Proxy (This would be the same application specified in the ProxyAppUrl attribute in the call to InvokeCASProxy method shown above)

Code Block
htmlhtml <%@ Page Language="VB" %> <script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) If CASAuthentication.IsAuthenticated Then


</script>

<html>
<head>
    <title>Proxy Callback Url Page</title>
</head>
<body>
</body>
</html>

The CAS Proxy (This would be the same application specified in the ProxyAppUrl attribute in the call to InvokeCASProxy method shown above)

Panel
borderColor#cccccc
bgColor#ffffff
titleBGColor#eeeeee
borderStyledashed
titleCASProxy.aspx


Span
stylebackground-color:yellow
idhl
<%

@ Page Language="VB"

Span
stylebackground-color:yellow
idhl
%>


<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs)

        If CASAuthentication.IsAuthenticated Then
            Response.Write("Welcome

"

&

CASAuthentication.CalNetID

&

",

you

have

been

successfully

authenticated

with

CAS!")


            Response.Write("<BR>")

Dim proxyArgs As StringBuilder = New StringBuilder Dim proxyArgKey As String = String.Empty ' 'Since this is the proxy application, we will check it's arguments it was sent 'Normally we would know if the arguments were sent in the query string or Form post 'but for the purposes of this example, we will check both ' If Request.QueryString.Count > 0 Then 'get arguments from querystring object For Each proxyArgKey In Request.QueryString

            Dim proxyArgs As StringBuilder = New StringBuilder
            Dim proxyArgKey As String= String.Empty

'
'Since this is the proxy application, we will check it's arguments it was sent
'Normally we would know if the arguments were sent in the query string or Form post
'but for the purposes of this example, we will check both
'

            If Request.QueryString.Count > 0 Then
                'get arguments from querystring object
                For Each proxyArgKey In Request.QueryString
                    proxyArgs.AppendFormat("{0}={1}

(query

string)<br>",

proxyArgKey,

Request.QueryString.Get(proxyArgKey)

) Next Else 'get arguments from form object For Each proxyArgKey In Request.Form

)
                Next
            Else
                'get arguments from form object
                For Each proxyArgKey In Request.Form
                    proxyArgs.AppendFormat("{0}={1}

(form

post)<br>",

proxyArgKey,

Request.Form.Get(proxyArgKey))

Next End If


                Next
            EndIf

            Response.Write(proxyArgs.ToString)


            Response.Write("<BR>"

) If Not

)

            If Not String.IsNullOrEmpty(CASAuthentication.Proxies)

Then Response

Then
               Response.Write(CASAuthentication.Proxies)


               Response.Write("

<BR>") End If End If End Sub </script> <html> <head> <title>Test CAS Proxied Application</title> </head> <body> <a

<BR>")
            End If
        End If

    End Sub
</script>

<html>
<head>
    <title>Test CAS Proxied Application</title>
</head>
<body>
    <a href="LogOut.aspx"

>Log

>Log out

of

CAS</a> </body> </html>

CAS</a>
</body>
</html>