|
|
| 1 2 |
|
William G. Thompson, Jr.-2
|
Folks,
Initially when I started the port of the Java CasClient to .Net I assumed since HttpModules are analogous to ServetFilters that it would be relatively straight mapping from Filters to HttpModules. However, as I dig deeper into .Net and the HttpRequest/FormsAuthentication lifecycle this turns out not to be so simple. For one, HttpModules and ServletFilters are not exactly at the same level of abstraction, HttpModules being a bit lower level (i.e. HttpSession may not be available depending on what events have fired). The other complication is the HttpApplication pipeline itself, which fires a mess of events and may make multiple calls into individual Modules which is a different behavior than Filters. So, I'm started to come around to the approach taking by the FormApplicationModule itself, as demonstrated by Reflector, Mono[1], and Michael Barton. I think we end up with one CasHttpModule that handles two events and is configured with the Cas specific components for handling ticket validation and setting up Context.User. I'd like to end up at place that has these characteristics: 1) dead simple easy deploy (drop in dll, a few web.conf settings) 2) excellent integration with .Net framework (Context.User, etc.) 3) feature/quality parity with Java client (good unit tests, support for saml, etc) Thoughts? Bill [1] Mono FormsAuthenticationModule: http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.aspx -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Winfrey, Catherine
|
Could you provide a reference for " FormApplicationModule itself, as
demonstrated by Reflector, Mono[1], and Michael Barton" so that I understand your approach a little better? Or do you mean FormsAuthenticationModule? I have done some testing with HttpModules as well and agree that they are a bit different from the ServletFilters. I have had some success with them but thus far only with the Authentication step of the processing. I am doing some more testing now. -----Original Message----- From: William G. Thompson, Jr. [mailto:[hidden email]] Sent: Thursday, March 26, 2009 14:06 To: [hidden email] Subject: [cas-dev] .Net JasigCasClient Folks, Initially when I started the port of the Java CasClient to .Net I assumed since HttpModules are analogous to ServetFilters that it would be relatively straight mapping from Filters to HttpModules. However, as I dig deeper into .Net and the HttpRequest/FormsAuthentication lifecycle this turns out not to be so simple. For one, HttpModules and ServletFilters are not exactly at the same level of abstraction, HttpModules being a bit lower level (i.e. HttpSession may not be available depending on what events have fired). The other complication is the HttpApplication pipeline itself, which fires a mess of events and may make multiple calls into individual Modules which is a different behavior than Filters. So, I'm started to come around to the approach taking by the FormApplicationModule itself, as demonstrated by Reflector, Mono[1], and Michael Barton. I think we end up with one CasHttpModule that handles two events and is configured with the Cas specific components for handling ticket validation and setting up Context.User. I'd like to end up at place that has these characteristics: 1) dead simple easy deploy (drop in dll, a few web.conf settings) 2) excellent integration with .Net framework (Context.User, etc.) 3) feature/quality parity with Java client (good unit tests, support for saml, etc) Thoughts? Bill [1] Mono FormsAuthenticationModule: http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.asp x -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
|
William G. Thompson, Jr.-2
|
Yes, I meant FormsAuthenticationModule:
http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.aspx Essentially on an AuthenticateRequest you check for CAS ticket/validation and also do FormsAuthenticationTicket logistics. The CAS Redirect is done on the EndRequest event if .Net was going to send a 401. The process feels odd from a Filter perspective, so I'm trusting this is the right way to do based on HttpApplication events as demonstrated by the mono code. Bill On Thu, Mar 26, 2009 at 3:52 PM, Winfrey, Catherine <[hidden email]> wrote: > Could you provide a reference for " FormApplicationModule itself, as > demonstrated by Reflector, Mono[1], > and Michael Barton" so that I understand your approach a little better? Or > do you mean FormsAuthenticationModule? > > I have done some testing with HttpModules as well and agree that they are a > bit different from the ServletFilters. I have had some success with them > but thus far only with the Authentication step of the processing. I am > doing some more testing now. > > -----Original Message----- > From: William G. Thompson, Jr. [mailto:[hidden email]] > Sent: Thursday, March 26, 2009 14:06 > To: [hidden email] > Subject: [cas-dev] .Net JasigCasClient > > Folks, > > Initially when I started the port of the Java CasClient to .Net I > assumed since HttpModules are analogous to ServetFilters that it would > be relatively straight mapping from Filters to HttpModules. However, > as I dig deeper into .Net and the HttpRequest/FormsAuthentication > lifecycle this turns out not to be so simple. For one, HttpModules > and ServletFilters are not exactly at the same level of abstraction, > HttpModules being a bit lower level (i.e. HttpSession may not be > available depending on what events have fired). The other > complication is the HttpApplication pipeline itself, which fires a > mess of events and may make multiple calls into individual Modules > which is a different behavior than Filters. > > So, I'm started to come around to the approach taking by the > FormApplicationModule itself, as demonstrated by Reflector, Mono[1], > and Michael Barton. I think we end up with one CasHttpModule that > handles two events and is configured with the Cas specific components > for handling ticket validation and setting up Context.User. > > I'd like to end up at place that has these characteristics: > 1) dead simple easy deploy (drop in dll, a few web.conf settings) > 2) excellent integration with .Net framework (Context.User, etc.) > 3) feature/quality parity with Java client (good unit tests, support > for saml, etc) > > Thoughts? > > Bill > > [1] Mono FormsAuthenticationModule: > http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.asp > x > > -- > You are currently subscribed to [hidden email] as: [hidden email] > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Scott Holodak
|
In reply to this post
by Winfrey, Catherine
Hi,
I've been reading, but haven't posted to this list yet. Here's my 2 sentence introduction: I maintain a .NET application for Rutgers that uses CAS. I worked under Bill Thompson on the project for about a year and got a very quick crash course on CAS from Scott Battaglia. Now here's my very long message: The CAS implementation we went with sits on top of Forms Authentication and basically shoehorns the CAS behavior into the Login page. Forms authentication and ASP.NET takes care of locking users on the login page (via the Forms Authentication and/or the URL authorization). The login page took care of ticket validation. We used a SqlMembershipProvider as a user list and (using a standard password for every user in the SqlMembershipProvider--we're not using SqlMembershipProvider to check/reset passwords). We then use the SqlRoleProvider for all roles on those usernames. In other words, we used CAS To determine whether a user had a valid Rutgers username/password, used the username that CAS returns to check the SqlMembershipProvider using a default password for everyone (to make sure that the valid Rutgers user was allowed to access the app), then called FormsAuthentication.RedirectFromLoginPage. Not terribly elegant, but pretty easy to get up and running quickly. If it sounds unsafe, I'm not explaining it correctly--the SqlMembershipProvider isn't the password authority, CAS is. Modeling CAS Authentication after the Forms Authentication provider is not a bad idea, but it's non-trivial. The module is just one piece of the puzzle. The AuthenticateRequest event fires on every single request, so you would need to store the CAS ticket in a cookie and validate that cookie--quickly. You would want to be able to trust the cookie until it expires (and prevent tampering) and optionally push the expiration out whenever a new request comes in--don't validate the ticket on every request. Setting the cookie would probably have to take place in a custom membership provider. The HttpModule is just one piece of the Forms Authentication puzzle. The FormsAuthentication classes are sealed/non-inheritible/non-overridable. There are about 20 classes that make it all work. Without being able to get at/alter the plumbing underneath Forms authentication, I'm not sure where you would set the CAS cookie, and what order the HTTP modules are fired in order to authenticate the requests. The relationship between the Forms Authentication and the Membership Providers is difficult to dissect and I'm not sure that there is a way to add another authentication type besides Forms and Passport (web.config:configuration\system.web\authentication\[forms|passport]). I couldn't find the configSections defined anywhere in the .config files in c:\windows\Microsoft.NET\Framework\v2.0.50727\CONFIG. The passport provider is a lot like what CAS is doing. I think it has been replaced by the Windows Live SDK. This is MS's single-sign-on implementation. The sample C# code in the Windows Live SDK looks like it short circuits the authentication provider model, but the original Passport provider code might be a good place to start disassembling or looking at Mono. If it's possible to implement a Passport provider, most of the heavy lifting might already be taken care by the code included in the framework. I'm not sure how much time I'd have time to contribute to the actual coding, but I'm happy to help out in whatever way I can. I would very much like to pull out my implementation and plug in a tested .dll & configuration. I'd also like to see if/how this is done. Here are some resources that might be useful: - http://msdn.microsoft.com/en-us/asp.net/aa336558.aspx Introduction to the Provider Model Introduction to the Provider Model Membership Providers Deep Dive on the ASP.NET Providers Microsoft ASP.NET 2.0 Providers: Introduction Membership Providers - http://msdn.microsoft.com/en-us/library/bb404787.aspx - http://go.microsoft.com/fwlink/?LinkID=86932&clcid=0x409 If you decide not to go the low-level way, another approach would be to implement a CasLogin control for login pages that takes care of redirecting users to the CAS login screen & validating the CAS ticket on the return trip, making the calls to the FormsAuthentication methods automatically. That could be packaged into a DLL, but it's not as pretty. Scott Holodak Rutgers University -----Original Message----- From: Winfrey, Catherine [mailto:[hidden email]] Sent: Thursday, March 26, 2009 3:53 PM To: [hidden email] Subject: RE: [cas-dev] .Net JasigCasClient Could you provide a reference for " FormApplicationModule itself, as demonstrated by Reflector, Mono[1], and Michael Barton" so that I understand your approach a little better? Or do you mean FormsAuthenticationModule? I have done some testing with HttpModules as well and agree that they are a bit different from the ServletFilters. I have had some success with them but thus far only with the Authentication step of the processing. I am doing some more testing now. -----Original Message----- From: William G. Thompson, Jr. [mailto:[hidden email]] Sent: Thursday, March 26, 2009 14:06 To: [hidden email] Subject: [cas-dev] .Net JasigCasClient Folks, Initially when I started the port of the Java CasClient to .Net I assumed since HttpModules are analogous to ServetFilters that it would be relatively straight mapping from Filters to HttpModules. However, as I dig deeper into .Net and the HttpRequest/FormsAuthentication lifecycle this turns out not to be so simple. For one, HttpModules and ServletFilters are not exactly at the same level of abstraction, HttpModules being a bit lower level (i.e. HttpSession may not be available depending on what events have fired). The other complication is the HttpApplication pipeline itself, which fires a mess of events and may make multiple calls into individual Modules which is a different behavior than Filters. So, I'm started to come around to the approach taking by the FormApplicationModule itself, as demonstrated by Reflector, Mono[1], and Michael Barton. I think we end up with one CasHttpModule that handles two events and is configured with the Cas specific components for handling ticket validation and setting up Context.User. I'd like to end up at place that has these characteristics: 1) dead simple easy deploy (drop in dll, a few web.conf settings) 2) excellent integration with .Net framework (Context.User, etc.) 3) feature/quality parity with Java client (good unit tests, support for saml, etc) Thoughts? Bill [1] Mono FormsAuthenticationModule: http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.asp x -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
Hi Scott!
Welcome to the Jasig cas-dev list and thanks for the thoughtful post. The fact that AuthenticateRequest fires every time really threw me for a while. I had imagined that this would only fire when an unauthenticated user tried to access a protected resource, but as you rightly point out it fires on every request. I don't think we necessarily have to store the CAS ticket in the FAT cookie though, we should be fine just with whatever FormsAuthN needs to tie the request back to the user. I'll check out the provider links, a Passport provider sounds interesting. Just to remind everyone, I've got a draft port of the code (1.0 protocol) in the sandbox at, https://www.ja-sig.org/svn/sandbox/JasigCasClient It's not yet functional, but I'm hoping to at least use the CAS domain classes in a working solution. I'm finding that SVNMonitor is a really handy tool to keep abreast of commit activity. http://www.svnmonitor.com/default.shtml Cheers, Bill On Thu, Mar 26, 2009 at 5:47 PM, Scott Holodak <[hidden email]> wrote: > Hi, > > I've been reading, but haven't posted to this list yet. Here's my 2 sentence introduction: > > I maintain a .NET application for Rutgers that uses CAS. I worked under Bill Thompson on the project for about a year and got a very quick crash course on CAS from Scott Battaglia. > > > Now here's my very long message: > > The CAS implementation we went with sits on top of Forms Authentication and basically shoehorns the CAS behavior into the Login page. Forms authentication and ASP.NET takes care of locking users on the login page (via the Forms Authentication and/or the URL authorization). The login page took care of ticket validation. We used a SqlMembershipProvider as a user list and (using a standard password for every user in the SqlMembershipProvider--we're not using SqlMembershipProvider to check/reset passwords). We then use the SqlRoleProvider for all roles on those usernames. > > In other words, we used CAS To determine whether a user had a valid Rutgers username/password, used the username that CAS returns to check the SqlMembershipProvider using a default password for everyone (to make sure that the valid Rutgers user was allowed to access the app), then called FormsAuthentication.RedirectFromLoginPage. Not terribly elegant, but pretty easy to get up and running quickly. If it sounds unsafe, I'm not explaining it correctly--the SqlMembershipProvider isn't the password authority, CAS is. > > Modeling CAS Authentication after the Forms Authentication provider is not a bad idea, but it's non-trivial. The module is just one piece of the puzzle. The AuthenticateRequest event fires on every single request, so you would need to store the CAS ticket in a cookie and validate that cookie--quickly. You would want to be able to trust the cookie until it expires (and prevent tampering) and optionally push the expiration out whenever a new request comes in--don't validate the ticket on every request. Setting the cookie would probably have to take place in a custom membership provider. The HttpModule is just one piece of the Forms Authentication puzzle. The FormsAuthentication classes are sealed/non-inheritible/non-overridable. There are about 20 classes that make it all work. Without being able to get at/alter the plumbing underneath Forms authentication, I'm not sure where you would set the CAS cookie, and what order the HTTP modules are fired in order to authenticate the requests. > > The relationship between the Forms Authentication and the Membership Providers is difficult to dissect and I'm not sure that there is a way to add another authentication type besides Forms and Passport (web.config:configuration\system.web\authentication\[forms|passport]). I couldn't find the configSections defined anywhere in the .config files in c:\windows\Microsoft.NET\Framework\v2.0.50727\CONFIG. > > The passport provider is a lot like what CAS is doing. I think it has been replaced by the Windows Live SDK. This is MS's single-sign-on implementation. The sample C# code in the Windows Live SDK looks like it short circuits the authentication provider model, but the original Passport provider code might be a good place to start disassembling or looking at Mono. > > If it's possible to implement a Passport provider, most of the heavy lifting might already be taken care by the code included in the framework. > > I'm not sure how much time I'd have time to contribute to the actual coding, but I'm happy to help out in whatever way I can. I would very much like to pull out my implementation and plug in a tested .dll & configuration. I'd also like to see if/how this is done. > > Here are some resources that might be useful: > - http://msdn.microsoft.com/en-us/asp.net/aa336558.aspx > Introduction to the Provider Model > Introduction to the Provider Model > Membership Providers > Deep Dive on the ASP.NET Providers > Microsoft ASP.NET 2.0 Providers: Introduction > Membership Providers > - http://msdn.microsoft.com/en-us/library/bb404787.aspx > - http://go.microsoft.com/fwlink/?LinkID=86932&clcid=0x409 > > If you decide not to go the low-level way, another approach would be to implement a CasLogin control for login pages that takes care of redirecting users to the CAS login screen & validating the CAS ticket on the return trip, making the calls to the FormsAuthentication methods automatically. That could be packaged into a DLL, but it's not as pretty. > > Scott Holodak > Rutgers University > > -----Original Message----- > From: Winfrey, Catherine [mailto:[hidden email]] > Sent: Thursday, March 26, 2009 3:53 PM > To: [hidden email] > Subject: RE: [cas-dev] .Net JasigCasClient > > Could you provide a reference for " FormApplicationModule itself, as > demonstrated by Reflector, Mono[1], > and Michael Barton" so that I understand your approach a little better? Or > do you mean FormsAuthenticationModule? > > I have done some testing with HttpModules as well and agree that they are a > bit different from the ServletFilters. I have had some success with them > but thus far only with the Authentication step of the processing. I am > doing some more testing now. > > -----Original Message----- > From: William G. Thompson, Jr. [mailto:[hidden email]] > Sent: Thursday, March 26, 2009 14:06 > To: [hidden email] > Subject: [cas-dev] .Net JasigCasClient > > Folks, > > Initially when I started the port of the Java CasClient to .Net I > assumed since HttpModules are analogous to ServetFilters that it would > be relatively straight mapping from Filters to HttpModules. However, > as I dig deeper into .Net and the HttpRequest/FormsAuthentication > lifecycle this turns out not to be so simple. For one, HttpModules > and ServletFilters are not exactly at the same level of abstraction, > HttpModules being a bit lower level (i.e. HttpSession may not be > available depending on what events have fired). The other > complication is the HttpApplication pipeline itself, which fires a > mess of events and may make multiple calls into individual Modules > which is a different behavior than Filters. > > So, I'm started to come around to the approach taking by the > FormApplicationModule itself, as demonstrated by Reflector, Mono[1], > and Michael Barton. I think we end up with one CasHttpModule that > handles two events and is configured with the Cas specific components > for handling ticket validation and setting up Context.User. > > I'd like to end up at place that has these characteristics: > 1) dead simple easy deploy (drop in dll, a few web.conf settings) > 2) excellent integration with .Net framework (Context.User, etc.) > 3) feature/quality parity with Java client (good unit tests, support > for saml, etc) > > Thoughts? > > Bill > > [1] Mono FormsAuthenticationModule: > http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.asp > x > > -- > You are currently subscribed to [hidden email] as: [hidden email] > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev > > > -- > You are currently subscribed to [hidden email] as: [hidden email] > To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
In reply to this post
by William G. Thompson, Jr.-2
Folks,
OK. After regrouping and going after a more .Net approach, the current sandbox builds and authenticates against CAS 1.0 protocol. The sample web app in the project can be configured (web.conf) to point to a CAS server of your choosing so you can quickly test it out and step through the client code. There is still much to do, and we're a long way off of anyone putting this into production...but we may have a decent path now. http://developer.jasig.org/source/browse/jasigsvn/sandbox/JasigCasClient I tried to simplify things a bit and cut down on the abstract layers in the Java version. We may need to add them back in as the protocol support grows, but I'd rather start simple and get it working. The key parts to look at if you are interested are: JasigCasClient.CasAuthenticationModule - this is the main client class and the only HttpModule JasigCasClient.Security ICasPrincipal CasPrincipal IAssertion Assertion JasigCasClient.Validation ITicketValidator AbstractUrlTicketValidator Cas10TicketValidator Still left to do: * CAS 2.0 and proxy tickets * Unit tests, unit tests, unit tests * A good set of .Net FormAuthN integration tests * SAML ... We might need to start thinking about a JIRA instance. Cheers, Bill On Thu, Mar 26, 2009 at 2:05 PM, William G. Thompson, Jr. <[hidden email]> wrote: > Folks, > > Initially when I started the port of the Java CasClient to .Net I > assumed since HttpModules are analogous to ServetFilters that it would > be relatively straight mapping from Filters to HttpModules. However, > as I dig deeper into .Net and the HttpRequest/FormsAuthentication > lifecycle this turns out not to be so simple. For one, HttpModules > and ServletFilters are not exactly at the same level of abstraction, > HttpModules being a bit lower level (i.e. HttpSession may not be > available depending on what events have fired). The other > complication is the HttpApplication pipeline itself, which fires a > mess of events and may make multiple calls into individual Modules > which is a different behavior than Filters. > > So, I'm started to come around to the approach taking by the > FormApplicationModule itself, as demonstrated by Reflector, Mono[1], > and Michael Barton. I think we end up with one CasHttpModule that > handles two events and is configured with the Cas specific components > for handling ticket validation and setting up Context.User. > > I'd like to end up at place that has these characteristics: > 1) dead simple easy deploy (drop in dll, a few web.conf settings) > 2) excellent integration with .Net framework (Context.User, etc.) > 3) feature/quality parity with Java client (good unit tests, support > for saml, etc) > > Thoughts? > > Bill > > [1] Mono FormsAuthenticationModule: > http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.aspx > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
I tagged this as Milestone 1 (JCC-1-0-0-M1).
http://developer.jasig.org/source/browse/jasigsvn/sandbox/JasigCasClient/tags/JCC-1-0-0-M1 Bill On Sun, Mar 29, 2009 at 12:14 AM, William G. Thompson, Jr. <[hidden email]> wrote: > Folks, > > OK. After regrouping and going after a more .Net approach, the > current sandbox builds and authenticates against CAS 1.0 protocol. > The sample web app in the project can be configured (web.conf) to > point to a CAS server of your choosing so you can quickly test it out > and step through the client code. There is still much to do, and > we're a long way off of anyone putting this into production...but we > may have a decent path now. > > http://developer.jasig.org/source/browse/jasigsvn/sandbox/JasigCasClient > > I tried to simplify things a bit and cut down on the abstract layers > in the Java version. We may need to add them back in as the protocol > support grows, but I'd rather start simple and get it working. The > key parts to look at if you are interested are: > > JasigCasClient.CasAuthenticationModule - this is the main client class > and the only HttpModule > > JasigCasClient.Security > ICasPrincipal > CasPrincipal > IAssertion > Assertion > > JasigCasClient.Validation > ITicketValidator > AbstractUrlTicketValidator > Cas10TicketValidator > > Still left to do: > * CAS 2.0 and proxy tickets > * Unit tests, unit tests, unit tests > * A good set of .Net FormAuthN integration tests > * SAML > ... > > We might need to start thinking about a JIRA instance. > > Cheers, > Bill > > On Thu, Mar 26, 2009 at 2:05 PM, William G. Thompson, Jr. > <[hidden email]> wrote: >> Folks, >> >> Initially when I started the port of the Java CasClient to .Net I >> assumed since HttpModules are analogous to ServetFilters that it would >> be relatively straight mapping from Filters to HttpModules. However, >> as I dig deeper into .Net and the HttpRequest/FormsAuthentication >> lifecycle this turns out not to be so simple. For one, HttpModules >> and ServletFilters are not exactly at the same level of abstraction, >> HttpModules being a bit lower level (i.e. HttpSession may not be >> available depending on what events have fired). The other >> complication is the HttpApplication pipeline itself, which fires a >> mess of events and may make multiple calls into individual Modules >> which is a different behavior than Filters. >> >> So, I'm started to come around to the approach taking by the >> FormApplicationModule itself, as demonstrated by Reflector, Mono[1], >> and Michael Barton. I think we end up with one CasHttpModule that >> handles two events and is configured with the Cas specific components >> for handling ticket validation and setting up Context.User. >> >> I'd like to end up at place that has these characteristics: >> 1) dead simple easy deploy (drop in dll, a few web.conf settings) >> 2) excellent integration with .Net framework (Context.User, etc.) >> 3) feature/quality parity with Java client (good unit tests, support >> for saml, etc) >> >> Thoughts? >> >> Bill >> >> [1] Mono FormsAuthenticationModule: >> http://www.koders.com/csharp/fid4BEDC51250B2B507391467CF38C6F5F600579CCD.aspx >> > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Marvin Addison
|
I'm concerned about the integration with .NET forms authentication.
It looks like it would buy us a hook into a standardized authentication and authorization framework at the expense of a good deal more complication. Perhaps it's worth the trade off; what arguments in favor of integrating with forms can you make? My real concern is that reliance on forms authentication would complicate or preclude some use cases with IIS 7 integration, like protecting static resources or non-.NET applications like Sharepoint. Can you comment on that? Following is a concrete alternative to CasAuthenticationModule that is semantically much closer to the Java client that hopefully demonstrates we don't _have_ to integrate with .NET forms. void OnBeginRequest(object sender, EventArgs args) { HttpApplication app = (HttpApplication)sender; HttpRequest request = app.Context.Request; HttpResponse response = app.Context.Response; HttpCookie cookie = request.Cookies.Get(COOKIE_NAME); if (authenticatedUsers.ContainsKey(cookie.Value)) { // User has already authenticated // Check whether their CAS client "session" has expired DateTime lastSeen = authenticatedUsers[cookie.Value]; if (DateTime.Now.Subtract(lastSeen) > cookieTTL) { // Cookie expired, redirect to CAS response.Redirect(casLoginUrl); } else { // Update the time authenticated user was last seen authenticatedUsers[cookie.Value] = DateTime.Now; } } else if (request.QueryString.Get(ArtifactParameterName) != null) { // Request contains ticket -- try to validate it try { ICasPrincipal principal = ticketValidator.validate( request.QueryString.Get(ArtifactParameterName), GetServiceUrl(request)); cookie = CreateCasClientCookie(principal); authenticatedUsers.Add(cookie.Value, DateTime.Now); response.Cookies.Add(cookie); } catch (TicketValidationException e) { log.Warn("CAS service ticket validation failed.", e); response.StatusCode = 403; } } else { // Not authenticated response.Redirect(casLoginUrl); } } The only substantial semantic difference from the Java client is the explicit management of authenticated state since an HTTP session may not be available in all cases. M -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
On Mon, Mar 30, 2009 at 1:08 PM, Marvin Addison
<[hidden email]> wrote: > I'm concerned about the integration with .NET forms authentication. > It looks like it would buy us a hook into a standardized > authentication and authorization framework at the expense of a good > deal more complication. Perhaps it's worth the trade off; what > arguments in favor of integrating with forms can you make? Perhaps it's not :) I started to have the same thoughts as I was porting the mono module over to CAS support. The initial motivating factor was not to have to handle the "session" cookie maintenance, and take advantage of unknown .net forms authN magic. I'm all for making this a simple as possible and your example is definitely simpler. Is there any loss of .net integration going this route? Could I still take an app that is current using Forms authN and switch to CAS with a simple web.conf switch? I'd liked CAS to be transparent for apps that don't care about proxy. > My real > concern is that reliance on forms authentication would complicate or > preclude some use cases with IIS 7 integration, like protecting static > resources or non-.NET applications like Sharepoint. Can you comment > on that? I'm still coming up to speed on .Net, but I believe all the same modules are available in IIS 7. > > The only substantial semantic difference from the Java client is the > explicit management of authenticated state since an HTTP session may > not be available in all cases. > Right. Any thoughts on where to stash the ICasPrincipal between requests? Bill -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Scott Holodak
|
Hi,
It is possible to get ASP.NET URL Authorization working for static content on IIS 5/6. You can create a wildcard extension mapping to the ASP.NET handler in IIS. In other words, where IIS 5/6 normally only uses the ASP.NET ISAPI for .aspx, ashx, etc. extensions, you can configure ASP.NET to run for .* (which also works for paths without .'s). For instance http://myserver/myapp/doesnotexist/ or http://myserver/myapp/images/image.png can be setup to go through ASP.NET and you can handle them however you want (render content on the fly for the first url/bypass 404 or generate the PNG from a DB or something). This is how the ASP.NET Routing works on IIS6 (used by MVC). The downside is the performance hit of running through the ASP.NET ISAPI filter for otherwise static content. ... The code sample solves the problem of only letting valid users into the app and forcing users on the login screen when they aren't authenticated (it should probably be moved to OnAuthenticateRequest). Without making the IIS config changes for 5/6, I don't think it will protect access to static content either. With it configured/in IIS 7, you might also have to make adjustments to allow users to access images and static content referenced by the login page (assuming you can get URL authorization working). You would need to write your own/extend the Logout control to remove the cookie. Since it doesn't set the Thread.CurrentPrincipal or Context.User, it would prevent all other ASP.NET and .NET security features from treating the request as authenticated. I'm pretty sure, the LoginView and LoginStatus controls would be broken, as would Code Access Security, URL Authorization, and Role-based authorization. You would have to tweak this code to allow users to access pages that anonymous users are allowed to see (maybe an anonymous Default page with a restricted Members page). If you decided to set these on your own, I'm pretty sure that you'd need to take care of setting them before every request is processed, whereas Forms Authentication takes care of this for you. Forms Authentication cookies are signed and encrypted using the Machine key by default. Decryption and verification are handled by the framework. I don't have the CAS code in front of me, but if the result of CreateCasClientCookie() isn't long/complex enough, it might be possible to brute force your way into another user's identity by tampering with the cookies. Making CAS work with the built-in ASP.NET authentication providers (Forms/Passport) has its advantages. With the exception of the special code in the Login page to make CAS place nice with Windows Forms, every other feature of forms authentication is available. You don't have to worry about the cookie expiration, the login redirection, etc. All page and path-level security is set in web.config using the <location path=".."><system.web><authorization> tags. You don't have write any special code for Application events (BeginRequest, AuthenticateRequest/PostAuthenticateRequest, AuthorizeRequest/PostAuthorizeRequest). http://msdn.microsoft.com/en-us/library/ms998288.aspx -Scott -----Original Message----- From: William G. Thompson, Jr. [mailto:[hidden email]] Sent: Monday, March 30, 2009 8:35 PM To: [hidden email] Subject: Re: [cas-dev] .Net JasigCasClient ... > My real > concern is that reliance on forms authentication would complicate or > preclude some use cases with IIS 7 integration, like protecting static > resources or non-.NET applications like Sharepoint. Can you comment > on that? I'm still coming up to speed on .Net, but I believe all the same modules are available in IIS 7. ... void OnBeginRequest(object sender, EventArgs args) { HttpApplication app = (HttpApplication)sender; HttpRequest request = app.Context.Request; HttpResponse response = app.Context.Response; HttpCookie cookie = request.Cookies.Get(COOKIE_NAME); if (authenticatedUsers.ContainsKey(cookie.Value)) { // User has already authenticated // Check whether their CAS client "session" has expired DateTime lastSeen = authenticatedUsers[cookie.Value]; if (DateTime.Now.Subtract(lastSeen) > cookieTTL) { // Cookie expired, redirect to CAS response.Redirect(casLoginUrl); } else { // Update the time authenticated user was last seen authenticatedUsers[cookie.Value] = DateTime.Now; } } else if (request.QueryString.Get(ArtifactParameterName) != null) { // Request contains ticket -- try to validate it try { ICasPrincipal principal = ticketValidator.validate( request.QueryString.Get(ArtifactParameterName), GetServiceUrl(request)); cookie = CreateCasClientCookie(principal); authenticatedUsers.Add(cookie.Value, DateTime.Now); response.Cookies.Add(cookie); } catch (TicketValidationException e) { log.Warn("CAS service ticket validation failed.", e); response.StatusCode = 403; } } else { // Not authenticated response.Redirect(casLoginUrl); } } ... -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Marvin Addison
|
In reply to this post
by William G. Thompson, Jr.-2
> Is there any loss of .net integration going this route?
There could be loss of integration/functionality in the application using CAS if they expect a more native authentication/authorization framework like Forms. > Could I still > take an app that is current using Forms authN and switch to CAS with a > simple web.conf switch? That's an ambitious goal, and one that will be hard to meet in the Windows world. Since .NET is heavily integrated with the Windows environment, the notion of pluggable authentication is much less developed than in other frameworks. I can certainly see the value in avoiding application changes to use CAS authentication, but I do think it represents additional work if it's even possible at all. > Any thoughts on where to stash the ICasPrincipal between requests? In a module-scope data structure like a dictionary. My impl relied on a secure cookie with a cryptographically strong value (hash of ticket validation date + secure random + netid); that could be used as the key to look up the principal. We'd need an out-of-band worker process to periodically sweep that data structure for orphaned sessions, but that should be straightforward. M -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Scott Holodak
|
I think you'd want to add something like this in one of the application events (AuthenticeRequest/PostAuthenticateRequest ?):
ICasPrincipal principal = GetThePrincipalBackSomehow(); HttpContext.Current.User = principal; System.Threading.Thread.CurrentPrincipal = principal; See this blog post: http://www.leastprivilege.com/CommentView.aspx?guid=d4405bb6-dec9-470e-ad9e-fcada13a4b0f If you decide to store the principals on the server, your best bet would be in the Application collection (either directly or via a dictionary attached to it). That would make it accessible to any of the worker processes on the machine. It would break in a web farm scenario--in which case you'd need to store them in a database or some other storage accessible from any of the machines. I'm pretty sure Forms Auth stores the identity info encrypted on the client in an encrypted cookie and recreates a GenericPrincipal when the request authenticates. Take a look at the FormsAuthenticationTicket and FormsIdentity classes. This would avoid the need to store them on the server and would get around web farm/DNS round-robin/active-active clustering problems. If you do go the server storage route, this might be useful with regard to the cleanup routines: http://blogs.telerik.com/kevinbabcock/posts/08-07-24/Using_an_HttpModule_to_Run_a_Background_Service.aspx -Scott -----Original Message----- From: Marvin Addison [mailto:[hidden email]] Sent: Tuesday, March 31, 2009 1:39 PM To: [hidden email] Subject: Re: [cas-dev] .Net JasigCasClient > Any thoughts on where to stash the ICasPrincipal between requests? In a module-scope data structure like a dictionary. My impl relied on a secure cookie with a cryptographically strong value (hash of ticket validation date + secure random + netid); that could be used as the key to look up the principal. We'd need an out-of-band worker process to periodically sweep that data structure for orphaned sessions, but that should be straightforward. -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Marvin Addison
|
Scott,
You raise some interesting points and make some good suggestions. I think I'm going to experiment and investigate some before commenting further. But my main goals are simplicity of the codebase and integration with IIS7 via managed ISAPI plugin. I think some of the benefits you mentioned like code access security, authorization, and support for authentication controls would be beneficial but supplementary. In any case I want to test some things out and read more before going further in support of one strategy versus another. M -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Winfrey, Catherine
|
In reply to this post
by Marvin Addison
After much discussion here at VT, we still consider a CAS .Net client
that does not use Windows Forms Authentication (WFA) to be a better solution. I have checked in code that uses HttpModules but not WFA as a configurable option in the JasigCasClient sandbox. Pros / cons for the non-WFA approach: Pros: 1. simpler code 2. ability to use an event (AcquireRequestState) where the Http Session is available, allowing very simple code to maintain the CAS response Assertion information across Http requests 3. no side effects because of piggy-backing one authentication system on top of another (see web page for details) 4. should still be able to use IPrincipal and a custom membership provider for role authorization if desired 5. ability to easily tell very early in the process, and anywhere desired, if the Http Request represents a CAS-protected page (see web page for details) Cons: 1. potential need to provide a custom membership provider Pros / cons for the WFA approach: Pros: 1. more familiar to Windows developers 2. path for CAS-protected secure pages is set using the standard web.config location element Cons: 1. more complicated code 2. some side effects from piggy-backing CAS authentication on top of WFA (see web page for details) 3. the two events used (AuthenticateRequest and EndRequest) do not have access to the Http Session, which presents difficulties in maintaining the CAS response Assertion information across Http requests (see web page for details) 4. limited, at best, ability to tell if the Http Request represents a CAS-protected page (see web page for details) 5. more frequent round trips to the CAS server because of FAT timeout or FAT removal because of browser cookie policies (see web page for details) Details about these comparisons can be found at: https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:j asig Comments? -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
Hi Catherine,
Sorry it too so long to respond...a bit buried at the moment. Here's some stream of thought feedback... First, thanks for the SVN commits and your thoughtful post. I am very excited to see a budding community interested in a full featured JASIG .Net CAS client. The link to the comparison doc wrapped in my email...at first it didn't work for me, but then I saw the rest of the URL...anyway here it is again for others if they missed it: https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:jasig You refer to WFA as Windows Forms Authentication. It would probably be clearer and more accurate to call it ASP.NET Forms Authentication or Web Forms Authentication...no? Some more below inline... On Mon, Apr 27, 2009 at 11:03 AM, Winfrey, Catherine <[hidden email]> wrote: > After much discussion here at VT, we still consider a CAS .Net client > that does not use Windows Forms Authentication (WFA) to be a better > solution. I have checked in code that uses HttpModules but not WFA as a > configurable option in the JasigCasClient sandbox. > > Pros / cons for the non-WFA approach: > Pros: > 1. simpler code > 2. ability to use an event (AcquireRequestState) where the Http > Session is available, allowing very simple code to maintain the CAS > response Assertion information across Http requests What is stopping the WFA based module from also using this event/method? > 3. no side effects because of piggy-backing one authentication > system on top of another (see web page for details) I may be missing something, but I don't see either of the side effects listed as an issue. For #1 (Context.User), the behavior will be the normal behavior for ASP.NET applications. For #2, the same logic applies to any application that uses some token to manage a session. In the WFA case it just happens to be the FAT. > 4. should still be able to use IPrincipal and a custom membership > provider for role authorization if desired > 5. ability to easily tell very early in the process, and anywhere > desired, if the Http Request represents a CAS-protected page (see web > page for details) > Cons: > 1. potential need to provide a custom membership provider > > Pros / cons for the WFA approach: > Pros: > 1. more familiar to Windows developers > 2. path for CAS-protected secure pages is set using the standard > web.config location element > Cons: > 1. more complicated code > 2. some side effects from piggy-backing CAS authentication on top > of WFA (see web page for details) > 3. the two events used (AuthenticateRequest and EndRequest) do not > have access to the Http Session, which presents difficulties in > maintaining the CAS response Assertion information across Http requests > (see web page for details) > 4. limited, at best, ability to tell if the Http Request represents > a CAS-protected page (see web page for details) > 5. more frequent round trips to the CAS server because of FAT > timeout or FAT removal because of browser cookie policies (see web page > for details) I don't understand how this would cause more frequent trips to CAS. Wouldn't it be the same with either approach? > > Details about these comparisons can be found at: > https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:j > asig > > Comments? There may not be a right answer. Folks coming from a ASP.Net background with existing applications that they would like to CASifying might be more included to WFA model. Folks coming from a Java background might be more inclined to a simpler approach. If we get the CAS client domain model right, we should be able to have two approaches side by side leveraging mostly the same code. No? Bill -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Winfrey, Catherine
|
Web Forms Authentication sounds good (and still lets the WFA acronym okay
for my wiki page). My comments: 1. Use of a different events for the WFA approach. I tested this briefly and I dont think it will work, at least not without some kludging. If the JasiCasClient OnAuthenticate method is registered for the AcquireRequestState event rather than the AuthenticateRequest event, it never gets called for a secured page. When the AuthenticateRequest event doesnt establish an IsAuthenticated true state, the only other events fired are PostAuthenticate and EndRequest. 2. Side effects. I agree that these side effects probably are not issues in terms of things that would have to be worked around if the WFA approach is selected. I just think that the fact that the other approach avoids these types of issues makes it preferable. 3. Round trips to CAS login. For the non-WFA approach, additional login requests to the CAS server are avoided by using the presence of the IPrincipal in the session for authentication purposes. One of the biggest advantages I see to the non-WFA approach is the ease of access to the session in order to maintain the user information returned in the CAS response, especially for SAML 1.1, and make it available to the web page. Another is the simplicity of the code. -----Original Message----- From: William G. Thompson, Jr. [mailto:[hidden email]] Sent: Monday, May 04, 2009 15:47 To: [hidden email] Subject: Re: [cas-dev] .Net JasigCasClient Hi Catherine, Sorry it too so long to respond...a bit buried at the moment. Here's some stream of thought feedback... First, thanks for the SVN commits and your thoughtful post. I am very excited to see a budding community interested in a full featured JASIG .Net CAS client. The link to the comparison doc wrapped in my email...at first it didn't work for me, but then I saw the rest of the URL...anyway here it is again for others if they missed it: https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:jasig You refer to WFA as Windows Forms Authentication. It would probably be clearer and more accurate to call it ASP.NET Forms Authentication or Web Forms Authentication...no? Some more below inline... On Mon, Apr 27, 2009 at 11:03 AM, Winfrey, Catherine <[hidden email]> wrote: > After much discussion here at VT, we still consider a CAS .Net client > that does not use Windows Forms Authentication (WFA) to be a better > solution. I have checked in code that uses HttpModules but not WFA as a > configurable option in the JasigCasClient sandbox. > > Pros / cons for the non-WFA approach: > Pros: > 1. simpler code > 2. ability to use an event (AcquireRequestState) where the Http > Session is available, allowing very simple code to maintain the CAS > response Assertion information across Http requests > 3. no side effects because of piggy-backing one authentication > system on top of another (see web page for details) I may be missing something, but I don't see either of the side effects listed as an issue. For #1 (Context.User), the behavior will be the normal behavior for ASP.NET applications. For #2, the same logic applies to any application that uses some token to manage a session. In the WFA case it just happens to be the FAT. > 4. should still be able to use IPrincipal and a custom membership > provider for role authorization if desired > 5. ability to easily tell very early in the process, and anywhere > desired, if the Http Request represents a CAS-protected page (see web > page for details) > Cons: > 1. potential need to provide a custom membership provider > > Pros / cons for the WFA approach: > Pros: > 1. more familiar to Windows developers > 2. path for CAS-protected secure pages is set using the standard > web.config location element > Cons: > 1. more complicated code > 2. some side effects from piggy-backing CAS authentication on top > of WFA (see web page for details) > 3. the two events used (AuthenticateRequest and EndRequest) do not > have access to the Http Session, which presents difficulties in > maintaining the CAS response Assertion information across Http requests > (see web page for details) > 4. limited, at best, ability to tell if the Http Request represents > a CAS-protected page (see web page for details) > 5. more frequent round trips to the CAS server because of FAT > timeout or FAT removal because of browser cookie policies (see web page > for details) Wouldn't it be the same with either approach? > > Details about these comparisons can be found at: > https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:j > asig > > Comments? There may not be a right answer. Folks coming from a ASP.Net background with existing applications that they would like to CASifying might be more included to WFA model. Folks coming from a Java background might be more inclined to a simpler approach. If we get the CAS client domain model right, we should be able to have two approaches side by side leveraging mostly the same code. No? Bill -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
On Tue, May 5, 2009 at 1:39 PM, Winfrey, Catherine <[hidden email]> wrote:
> Web Forms Authentication sounds good (and still lets the WFA acronym okay > for my wiki page). OK. Just wanted to make sure we are talking about the same thing. :) > > My comments: > > 1. Use of a different events for the WFA approach. > I tested this briefly and I don’t think it will work, at least not without > some kludging. If the JasiCasClient OnAuthenticate method is registered for > the AcquireRequestState event rather than the AuthenticateRequest event, it > never gets called for a secured page. When the AuthenticateRequest event > doesn’t establish an IsAuthenticated true state, the only other events fired > are PostAuthenticate and EndRequest. Rather than register OnAuthenticate for AcquiredRequestState, I think one could leave it where it is and simply add a new handler method, OnAcquiredRequestState, that would check for a flag/object on HttpContext.Items and retrieve/store the CasPrincipal in the Session. The flag/object would be set by OnAuthenticate, and would either be the initial CasPrincipal or a flag based on the FAT to retrieve the CasPrincipal from the Session. "HttpContext.Items: Gets a key/value collection that can be used to organize and share data between an System.Web.IHttpModule interface and an System.Web.IHttpHandler interface during an HTTP request." > > 2. Side effects. > I agree that these side effects probably are not issues in terms of things > that would have to be worked around if the WFA approach is selected. I just > think that the fact that the other approach avoids these types of issues > makes it preferable. I still don't see how the issues are any different for either approach...maybe I'm still missing something. > > 3. Round trips to CAS login. > For the non-WFA approach, additional login requests to the CAS server are > avoided by using the presence of the IPrincipal in the session for > authentication purposes. I don't foresee the WFA approach needing additional CAS login requests. If we can't figure out how to effectively attach the CasPrincipal to a session we would indeed be sunk. The two approaches we have so far are serialization to the FAT cookie, or some hook into the Session. Both have their pros and cons, either one should be achievable. > One of the biggest advantages I see to the non-WFA approach is the ease of > access to the session in order to maintain the user information returned in > the CAS response, especially for SAML 1.1, and make it available to the web > page. Another is the simplicity of the code. I'm still of the mind that both approaches have their place, and that both should be able to leverage a common CAS client domain model. With either approach I would expect application code to be the same and look something like this: // existing APS.Net code should continue to work as is IPrincipal user = HttpContext.Current.User; user.IsInRole("student"); // potentially queries attributes returned via SAML 1.1. CAS response user.Identity.Name // returns name of the current user (i.e. Principal Name) // using extended Cas functionality should feel natural to ASP.Net ICasPrincipal user = HttpContext.Current.User; IProxyTicket ticket = user.GetProxyTicketFor("http://some.proxied.service/"); ILookup attributes = user.Assertion.Attributes; Best, Bill > > > -----Original Message----- > From: William G. Thompson, Jr. [mailto:[hidden email]] > Sent: Monday, May 04, 2009 15:47 > To: [hidden email] > Subject: Re: [cas-dev] .Net JasigCasClient > > Hi Catherine, > > Sorry it too so long to respond...a bit buried at the moment. Here's > some stream of thought feedback... > > First, thanks for the SVN commits and your thoughtful post. I am very > excited to see a budding community interested in a full featured JASIG > .Net CAS client. > > The link to the comparison doc wrapped in my email...at first it > didn't work for me, but then I saw the rest of the URL...anyway here > it is again for others if they missed it: > https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:jasig > > You refer to WFA as Windows Forms Authentication. It would probably > be clearer and more accurate to call it ASP.NET Forms Authentication > or Web Forms Authentication...no? > > Some more below inline... > > On Mon, Apr 27, 2009 at 11:03 AM, Winfrey, Catherine <[hidden email]> > wrote: >> After much discussion here at VT, we still consider a CAS .Net client >> that does not use Windows Forms Authentication (WFA) to be a better >> solution. I have checked in code that uses HttpModules but not WFA as a >> configurable option in the JasigCasClient sandbox. >> >> Pros / cons for the non-WFA approach: >> Pros: >> 1. simpler code >> 2. ability to use an event (AcquireRequestState) where the Http >> Session is available, allowing very simple code to maintain the CAS >> response Assertion information across Http requests > > What is stopping the WFA based module from also using this event/method? > >> 3. no side effects because of piggy-backing one authentication >> system on top of another (see web page for details) > > I may be missing something, but I don't see either of the side effects > listed as an issue. For #1 (Context.User), the behavior will be the > normal behavior for ASP.NET applications. For #2, the same logic > applies to any application that uses some token to manage a session. > In the WFA case it just happens to be the FAT. > > >> 4. should still be able to use IPrincipal and a custom membership >> provider for role authorization if desired >> 5. ability to easily tell very early in the process, and anywhere >> desired, if the Http Request represents a CAS-protected page (see web >> page for details) >> Cons: >> 1. potential need to provide a custom membership provider >> >> Pros / cons for the WFA approach: >> Pros: >> 1. more familiar to Windows developers >> 2. path for CAS-protected secure pages is set using the standard >> web.config location element >> Cons: >> 1. more complicated code >> 2. some side effects from piggy-backing CAS authentication on top >> of WFA (see web page for details) >> 3. the two events used (AuthenticateRequest and EndRequest) do not >> have access to the Http Session, which presents difficulties in >> maintaining the CAS response Assertion information across Http requests >> (see web page for details) >> 4. limited, at best, ability to tell if the Http Request represents >> a CAS-protected page (see web page for details) >> 5. more frequent round trips to the CAS server because of FAT >> timeout or FAT removal because of browser cookie policies (see web page >> for details) > > I don't understand how this would cause more frequent trips to CAS. > Wouldn't it be the same with either approach? > >> >> Details about these comparisons can be found at: >> https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:j >> asig >> >> Comments? > > There may not be a right answer. Folks coming from a ASP.Net > background with existing applications that they would like to > CASifying might be more included to WFA model. Folks coming from a > Java background might be more inclined to a simpler approach. If we > get the CAS client domain model right, we should be able to have two > approaches side by side leveraging mostly the same code. No? > > Bill > > -- > You are currently subscribed to [hidden email] as: [hidden email] > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Scott Holodak
|
In reply to this post
by William G. Thompson, Jr.-2
Hi Catherine, Bill,
Just a few points on the discussion: ==== Non-WFA Pros - simpler code: The biggest benefit of producing a WFA compatible provider is that the incorporating it into a web application could be as simple as droping a dll file in place and editing web.config. The difficulty in implementing the provider it is outweighed by the simplicitly of using it. Plus, I think more .NET developers would prefer to use something that fits the .NET model than something that resembles the Java implementation--especially if the users would consume the functionality in binary form anyway. ==== Non-WFA Pros - execution of CAS functionality in an event that allows access to the Http Session WFA - Cons - execution of CAS functionality must be in two events that do not allow access to the Http Session The 'Session' is a higher level concept in ASP.NET, but you don't need it handle caching a ticket. In fact, I would argue that it would be a design flaw to do so. Remember that the Session can be configured for multiple persistence mechanisms (cookie, server process memory, database, etc.). You would need to account for the implications of all of those--a web farm configuration doesn't have 'server process memory' as a viable option. I don't think they are all appropriate places to store the auth ticket anyway. Remember, at the lowest level, ASP.NET is just dealing with HTTP traffic. This is most likely why WFA uses a cookie (FormsAuthCookie) to store the credentials on the client. You can get at that cookie value all the way back in the BeginRequest event (before AuthenticateRequest, AuthorizeRequest, ResolveRequestCache, AcquireRequestState, etc.). Even if you're trying to get at the cookie so early in the request pipeline that the HttpContext.Request.Cookies collection isn't populated (I don't know if this is ever the case), you could still parse HttpContext.Current.Request.Headers["Cookie"]. ==== Non-WFA Cons - potential need to provide the custom MembershipProvider This is most likely true in either case. It's not that bad. I have a sample configuration provider for our LDAP server (non-Active Directory) that you can have as a reference. You just have to follow the provider model documentation carefully and make sure to throw the right exceptions in the right places. Also, you have to pay attention to thread safety. ==== WFA - Cons - side effects caused by piggy-backing two authentication systems Keep in mind that there is nothing forcing you to keep the piggybacking code embedded in the library. It would recommend creating a third MembershipProvider that performs AND/UNION/INTERSECTION type operations on other membership providers. I've been meaning to do this for a few years (also for the RoleProviders), but never got around to it. For example: <membership defaultProvider="MultipleSourceMembershipProvider"> <providers> <clear/> <add name="CasMembershipProvider" type="Edu.Rutgers.CasMembershipProvider" connectionstringname="CasConnection"/> <add name="SqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SqlConnection" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" applicationName="rex" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0"/> <add name="MultipleSourceMembershipProvider" type="Edu.Rutgers.MultipleSourceMembershipProvider" defaultProvider="SqlMembershipProvider" validateUserExpression="(CasMembershipProvider({$username}, {$password}) && SqlMembershipProvider({$username}, {{CONSTANT}}))" /> </providers> </membership> Something like this would be a proxy for all requests to SqlMembershipProvider except for the ValidateUser(string, password) method, which would be handled as return Membership.Providers["CasMembershipProvider"].ValidateUser(username, password) && Membership.Providers["SqlMembershipProvider"].ValidateUser(username, "CONSTANT"); Plus, it would be completely agnostic to the underlying types of providers. You could get your user list from Oracle, verify using Cas, change passwords with Active Directory, etc., etc. ==== WFA - Cons - very limited ability, in the event handler code, to distinguish CAS-protected web pages from anonymous access pages & WFA - Cons - more frequent redirects to the CAS server for logon I'm not sure I understand what you're saying here. It seems like you're blurring Authentication and Authorization. Every request should be authenticated. If I have a CAS ticket cookie, it just means verifying that the cookie hasn't been tampered with and making sure the HttpContext.Current.User and System.Threading.Thread.CurrentPrincipal are populated with an instance of a principal (i.e, GenericPrincipal). At that point, the Web Forms AUTHORIZATION subsystem becomes functional (Roles, Code Access security, web.config location/permission, Site map security pruning, Login controls, etc), as does the Profile subsystem. If I don't have a CAS ticket cookie, I should be authenticated as an anonymous user (empty principal). If I am attempting to access a page using a fake CAS ticket cookie, the cookie should be destroyed and the user should have be authenticated as an anonymous user (empty principal). The Authorization subsystem will take care of determining whether anonymous access is allowed on a particular page and whether it's necessary to kick the user back to the login page (based on whether the principal is valid). If you don't set HttpContext.Current.User and System.Threading.Thread.CurrentPrincipal, then your application will fail all Authorization checks, which is why you might be seeing excessive login page/CAS communication problems. Anonymous page access works fine with WFAuthentication & WFAuthorization and doesn't require re-authentication against whatever authentication source on each request--it simply requires validating the cookie. Your Authentication handler code should not care at all about whether the page allows anonymous access or not. That's the Authorization subsystem's responsibility. If the CAS provider is implemented correctly, it shouldn't be concerned with the AuthorizeRequest/PostAuthorizeRequest methods at all. -Scott ----- Original Message ----- From: "William G. Thompson, Jr." <[hidden email]> To: [hidden email] Sent: Wednesday, May 6, 2009 9:51:27 AM GMT -05:00 US/Canada Eastern Subject: Re: [cas-dev] .Net JasigCasClient On Tue, May 5, 2009 at 1:39 PM, Winfrey, Catherine <[hidden email]> wrote: > Web Forms Authentication sounds good (and still lets the WFA acronym okay > for my wiki page). OK. Just wanted to make sure we are talking about the same thing. :) > > My comments: > > 1. Use of a different events for the WFA approach. > I tested this briefly and I don’t think it will work, at least not without > some kludging. If the JasiCasClient OnAuthenticate method is registered for > the AcquireRequestState event rather than the AuthenticateRequest event, it > never gets called for a secured page. When the AuthenticateRequest event > doesn’t establish an IsAuthenticated true state, the only other events fired > are PostAuthenticate and EndRequest. Rather than register OnAuthenticate for AcquiredRequestState, I think one could leave it where it is and simply add a new handler method, OnAcquiredRequestState, that would check for a flag/object on HttpContext.Items and retrieve/store the CasPrincipal in the Session. The flag/object would be set by OnAuthenticate, and would either be the initial CasPrincipal or a flag based on the FAT to retrieve the CasPrincipal from the Session. "HttpContext.Items: Gets a key/value collection that can be used to organize and share data between an System.Web.IHttpModule interface and an System.Web.IHttpHandler interface during an HTTP request." > > 2. Side effects. > I agree that these side effects probably are not issues in terms of things > that would have to be worked around if the WFA approach is selected. I just > think that the fact that the other approach avoids these types of issues > makes it preferable. I still don't see how the issues are any different for either approach...maybe I'm still missing something. > > 3. Round trips to CAS login. > For the non-WFA approach, additional login requests to the CAS server are > avoided by using the presence of the IPrincipal in the session for > authentication purposes. I don't foresee the WFA approach needing additional CAS login requests. If we can't figure out how to effectively attach the CasPrincipal to a session we would indeed be sunk. The two approaches we have so far are serialization to the FAT cookie, or some hook into the Session. Both have their pros and cons, either one should be achievable. > One of the biggest advantages I see to the non-WFA approach is the ease of > access to the session in order to maintain the user information returned in > the CAS response, especially for SAML 1.1, and make it available to the web > page. Another is the simplicity of the code. I'm still of the mind that both approaches have their place, and that both should be able to leverage a common CAS client domain model. With either approach I would expect application code to be the same and look something like this: // existing APS.Net code should continue to work as is IPrincipal user = HttpContext.Current.User; user.IsInRole("student"); // potentially queries attributes returned via SAML 1.1. CAS response user.Identity.Name // returns name of the current user (i.e. Principal Name) // using extended Cas functionality should feel natural to ASP.Net ICasPrincipal user = HttpContext.Current.User; IProxyTicket ticket = user.GetProxyTicketFor("http://some.proxied.service/"); ILookup attributes = user.Assertion.Attributes; Best, Bill > > > -----Original Message----- > From: William G. Thompson, Jr. [mailto:[hidden email]] > Sent: Monday, May 04, 2009 15:47 > To: [hidden email] > Subject: Re: [cas-dev] .Net JasigCasClient > > Hi Catherine, > > Sorry it too so long to respond...a bit buried at the moment. Here's > some stream of thought feedback... > > First, thanks for the SVN commits and your thoughtful post. I am very > excited to see a budding community interested in a full featured JASIG > .Net CAS client. > > The link to the comparison doc wrapped in my email...at first it > didn't work for me, but then I saw the rest of the URL...anyway here > it is again for others if they missed it: > https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:jasig > > You refer to WFA as Windows Forms Authentication. It would probably > be clearer and more accurate to call it ASP.NET Forms Authentication > or Web Forms Authentication...no? > > Some more below inline... > > On Mon, Apr 27, 2009 at 11:03 AM, Winfrey, Catherine <[hidden email]> > wrote: >> After much discussion here at VT, we still consider a CAS .Net client >> that does not use Windows Forms Authentication (WFA) to be a better >> solution. I have checked in code that uses HttpModules but not WFA as a >> configurable option in the JasigCasClient sandbox. >> >> Pros / cons for the non-WFA approach: >> Pros: >> 1. simpler code >> 2. ability to use an event (AcquireRequestState) where the Http >> Session is available, allowing very simple code to maintain the CAS >> response Assertion information across Http requests > > What is stopping the WFA based module from also using this event/method? > >> 3. no side effects because of piggy-backing one authentication >> system on top of another (see web page for details) > > I may be missing something, but I don't see either of the side effects > listed as an issue. For #1 (Context.User), the behavior will be the > normal behavior for ASP.NET applications. For #2, the same logic > applies to any application that uses some token to manage a session. > In the WFA case it just happens to be the FAT. > > >> 4. should still be able to use IPrincipal and a custom membership >> provider for role authorization if desired >> 5. ability to easily tell very early in the process, and anywhere >> desired, if the Http Request represents a CAS-protected page (see web >> page for details) >> Cons: >> 1. potential need to provide a custom membership provider >> >> Pros / cons for the WFA approach: >> Pros: >> 1. more familiar to Windows developers >> 2. path for CAS-protected secure pages is set using the standard >> web.config location element >> Cons: >> 1. more complicated code >> 2. some side effects from piggy-backing CAS authentication on top >> of WFA (see web page for details) >> 3. the two events used (AuthenticateRequest and EndRequest) do not >> have access to the Http Session, which presents difficulties in >> maintaining the CAS response Assertion information across Http requests >> (see web page for details) >> 4. limited, at best, ability to tell if the Http Request represents >> a CAS-protected page (see web page for details) >> 5. more frequent round trips to the CAS server because of FAT >> timeout or FAT removal because of browser cookie policies (see web page >> for details) > > I don't understand how this would cause more frequent trips to CAS. > Wouldn't it be the same with either approach? > >> >> Details about these comparisons can be found at: >> https://www.middleware.vt.edu/doku.php?id=middleware:cas:client:dotnet:j >> asig >> >> Comments? > > There may not be a right answer. Folks coming from a ASP.Net > background with existing applications that they would like to > CASifying might be more included to WFA model. Folks coming from a > Java background might be more inclined to a simpler approach. If we > get the CAS client domain model right, we should be able to have two > approaches side by side leveraging mostly the same code. No? > > Bill > > -- > You are currently subscribed to [hidden email] as: [hidden email] > To unsubscribe, change settings or access archives, see > http://www.ja-sig.org/wiki/display/JSG/cas-dev > -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
William G. Thompson, Jr.-2
|
On Wed, May 6, 2009 at 11:53 AM, Scott Holodak <[hidden email]> wrote:
> Hi Catherine, Bill, > > Just a few points on the discussion: > > ==== > > Non-WFA Pros - simpler code: > > The biggest benefit of producing a WFA compatible provider is that the incorporating it into a web application could be as simple as droping a dll file in place and editing web.config. The difficulty in implementing the provider it is outweighed by the simplicitly of using it. Plus, I think more .NET developers would prefer to use something that fits the .NET model than something that resembles the Java implementation--especially if the users would consume the functionality in binary form anyway. > > ==== > > Non-WFA Pros - execution of CAS functionality in an event that allows access to the Http Session > WFA - Cons - execution of CAS functionality must be in two events that do not allow access to the Http Session > > The 'Session' is a higher level concept in ASP.NET, but you don't need it handle caching a ticket. In > fact, I would argue that it would be a design flaw to do so. Remember that the Session can be > configured for multiple persistence mechanisms (cookie, server process memory, database, etc.). You > would need to account for the implications of all of those--a web farm configuration doesn't have 'server > process memory' as a viable option. I don't think they are all appropriate places to store the auth ticket > anyway. Hi Scott. This issue is not so much as where to store the ticket as to where to cache the ICasPrinciple and IAssertion. In regular WFA the username is just stored in the FAT and the IPrincipal is re-created for every request. Typically, CAS clients store the CasPrincipal/Assertion in a server-memory cache (Session) that is tied to a specific session. Thoughts on where to store the ICasPrincipal/IAssertion? I was consider the Session and then adding another event handler to store/retrieve it into Context.User, etc. for each request. Bill -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
|
Winfrey, Catherine
|
That's the approach that I had in mind also, using a session object. My
wiki page has some information about different storage approaches that I had considered under the heading 'CAS Assertion Information Maintenance'. To use a second event that has access to the Http session, I believe we would also have to delay the redirect after ticket validation so that this event would fire. This delayed redirect state could also be communicated through the item collection. Also, Cathy is just fine. Sorry that I usually forget to include any type of signature. Cathy -----Original Message----- From: William G. Thompson, Jr. [mailto:[hidden email]] Sent: Wednesday, May 06, 2009 12:10 To: [hidden email] Subject: Re: [cas-dev] .Net JasigCasClient On Wed, May 6, 2009 at 11:53 AM, Scott Holodak <[hidden email]> wrote: > Hi Catherine, Bill, > > Just a few points on the discussion: > > ==== > > Non-WFA Pros - simpler code: > > The biggest benefit of producing a WFA compatible provider is that the incorporating it into a web application could be as simple as droping a dll file in place and editing web.config. The difficulty in implementing the provider it is outweighed by the simplicitly of using it. Plus, I think more .NET developers would prefer to use something that fits the .NET model than something that resembles the Java implementation--especially if the users would consume the functionality in binary form anyway. > > ==== > > Non-WFA Pros - execution of CAS functionality in an event that allows access to the Http Session > WFA - Cons - execution of CAS functionality must be in two events that do not allow access to the Http Session > > The 'Session' is a higher level concept in ASP.NET, but you don't need it handle caching a ticket. In > fact, I would argue that it would be a design flaw to do so. Remember that the Session can be > configured for multiple persistence mechanisms (cookie, server process memory, database, etc.). You > would need to account for the implications of all of those--a web farm configuration doesn't have 'server > process memory' as a viable option. I don't think they are all appropriate places to store the auth ticket > anyway. Hi Scott. This issue is not so much as where to store the ticket as to where to cache the ICasPrinciple and IAssertion. In regular WFA the username is just stored in the FAT and the IPrincipal is re-created for every request. Typically, CAS clients store the CasPrincipal/Assertion in a server-memory cache (Session) that is tied to a specific session. Thoughts on where to store the ICasPrincipal/IAssertion? I was consider the Session and then adding another event handler to store/retrieve it into Context.User, etc. for each request. Bill -- You are currently subscribed to [hidden email] as: [hidden email] To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |