0

It seems I was not expressing my question well, so I am adding this as a supplemental title: How can I extend the FormsAuthentication class so that I can override default behaviors in a configuration file (for example, pass off execution control to the MembershipProvider for updating the MembershipUser's LastActivity on a new page request), and, failing that, replace the mechanism of the FormsAuthentication class with my own custom class and use that as the FormsAuthentication class would normally be used?

How do we implement a less ridiculously rigid, more extensible FormsAuthentication framework that will allow us to integrate into a custom MembershipProvider? Has there been any work on this? Ultimately, I'd like to put in my web.config something like this:

<authentication mode="Forms">
    <forms membershipProvider="MyCustomMembershipProvider">
        <events>
            <add event="AuthenticatedRequest" action="OnAuthRequest" />
            <add event="UnAuthenticatedRequest" action="OnRequest" />
            <add event="UnAuthorizedRequest" action="UnAuthRequest" />
        </events>
    </forms>
</authentication>

This shouldn't be taking up all my time. The Forms Authentication seems to be pretty low-level in the ASP.NET page lifecycle, but there's got to be a way to cleanly circumvent it.

This is not about the custom membership provider. I want to implement things in my membership provider class like the implied "IsOnline" and "LastActivity" functionality, but the FormsAuthentication sets the cookie and doesn't look back. I want to inject my own code when it checks that cookie, but I can't. There has to be a way other than layering my own cookie on top.

Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254
  • possible duplicate of [Custom MembershipProvider in .NET 4.0](http://stackoverflow.com/questions/5701673/custom-membershipprovider-in-net-4-0) – jrummell Nov 08 '11 at 20:25
  • That is focused on the custom membership provider. My frustration is with the FormsAuthentication. I'll add more info to my question. – Jeremy Holovacs Nov 08 '11 at 20:29
  • It's not very clear what you want. You talk about custom-membership providers in your title, and your message, and then say that's not what you're talking about. You need to clarify exactly what you want. – Erik Funkenbusch Nov 08 '11 at 20:39
  • I want to have some control over pieces of the Forms Authentication so I can invoke parts of my custom membership provider. Right now, once you set that cookie, it's pretty much done with authentication until you sign out... but what if you want to track that cookie validation with each page request? You can't, there's no mechanism that exposes that. I want to update my LastActivity value based upon when that cookie is examined with each request. – Jeremy Holovacs Nov 08 '11 at 21:00

2 Answers2

1

Based on your update, you could create a custom membership provider as mentioned in the linked question that inherits from SqlMembershipProvider, overriding any functionality that you want to change.

You are correct in that Forms Authentication simply creates a cookie; that's all that its meant to do - help your application determine if your user is logged in. The Membership part is what tells you IsOnline and LastActivity and other user information.

If you could let us know what membership functionality you wish to override, we can try to help as you haven't given us enough detail yet.

Community
  • 1
  • 1
jrummell
  • 42,637
  • 17
  • 112
  • 171
  • I don't want to override membership functionality. I want to override the FormsAuthentication system so when my ASP.NET page validates the cookie from the client request, I can invoke a method in my membership provider to update the Last Activity in provider data store. – Jeremy Holovacs Nov 08 '11 at 20:55
  • You want membership functionally without membership. Have you read up on membership? Its the tried and true method of doing what you are trying to do. – jrummell Nov 08 '11 at 20:58
  • 1
    @JeremyHolovacs - the default .NET provider already updates the Last Activity field when a user is validated (there is a flag even to tell it whether or not to update this field). I don't understand why this doesn't work for you. – Erik Funkenbusch Nov 08 '11 at 20:59
  • It ONLY works when the user is validated. But that's not the last activity. Each page request does not update the Last Activity, and it should. – Jeremy Holovacs Nov 08 '11 at 21:01
  • You don't execute `GetUser(string, bool)` with every page refresh. At least I don't. And I don't want to... that's awfully heavy for a single field I need to update. You are trying to propose alternatives; I am aware there are alternatives. I want to pursue replacing and or supplementing the forms authentication mechanism with something that will allow an efficient update. – Jeremy Holovacs Nov 08 '11 at 21:09
  • @JeremyHolovacs - That's because Membership is not called on each page request. You could add a call to GetUser, update the last activity date, then call UpdateUser on each page request. You add this code to the global.asax in the Application_PostAuthorizeRequest event. Simple, and easy without all the complication you are trying to create. – Erik Funkenbusch Nov 08 '11 at 21:14
  • That may be the direction I have to pursue. I was really hoping to write a group of providers that would just have to be referenced in a web.config and work, but it does not appear that is possible. – Jeremy Holovacs Nov 08 '11 at 21:18
1

No, it doesn't work that way. The membership provider doesn't get authenticated requests or unauthenticated requests. In fact, it has very little to do with authentication. That's handled by the security framework. Membership is only used as the means to validate someones username and password. That's it. You can think of Membership as a data store that the security framework uses to authenticate the user, but it does not do the management of the authentication itself.

This article might be what you're looking for:

http://www.asp.net/security/tutorials/forms-authentication-configuration-and-advanced-topics-cs

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • I know it doesn't work like this; this is part of my frustration. We should be able to make it work like this though. `FormsAuthentication.Authenticate()` and `MembershipProvider.ValidateUser()` are ultimately related in spirit, while not in reality. My problem is, these two mechanisms touch each other quite often at authentication, and then don't even acknowledge each other. These are inherently related security structures; they should be able to communicate. – Jeremy Holovacs Nov 08 '11 at 20:50
  • @JeremyHolovacs - It's pointless to lament over the how poorly this is designed. It's designed the way it is, and there's not much you can do about it, other than not using it. Just accept that, and move on with either using it, or doing something else. – Erik Funkenbusch Nov 08 '11 at 20:58
  • Are you serious? The whole point of this site is to find better ways of doing things, explore new possibilities, and address frustrations with solutions. Your philosophy would still have us banging on rocks in a cave somewhere. If you don't know an answer, that's OK, but don't try to shut it down because it hasn't been seriously considered before. There are solutions; there have to be. – Jeremy Holovacs Nov 08 '11 at 21:03
  • @JeremyHolovacs - You can't do what you want. It's not an "i don't know an answer", it's just not possible. You can't make the built-in forms authentication do what you want it to do. So there is no point in "wishing" you could. You either need to replace FormsAuthentication with your own code, or work within its limitations. Your problem is that you're dead set on a specific implementation, and want the built-in framework to work that way when it doesn't. It's like wishing water wasn't wet, and argue with someone that tells you that you can't change it, that's the way water is. – Erik Funkenbusch Nov 08 '11 at 21:07
  • @JeremyHolovacs I don't know if you noticed his awesomely high rep score, but Mystere Man definitely knows what he's talking about. – jrummell Nov 08 '11 at 21:07
  • @MystereMan: your last comment is a viable answer to the question I asked. If there is no way to do what I want to do, then I need to explore other avenues, but until you said that my question was unanswered. – Jeremy Holovacs Nov 08 '11 at 21:12
  • @jrummell I was not questioning his expertise, but I was getting quite frustrated at the fact that we had all this dialog and the answer is apparently "you can't implement a custom piece of code to replace the security framework." – Jeremy Holovacs Nov 08 '11 at 21:14
  • @JeremyHolovacs - Part of the problem is that your question was vague, and we had to drag what you REALLY wanted out of you. You really have nobody to blame but yourself for asking such a vague question, and not really asking the question you wanted. The fact is, the FormsAuthentication code is very tightly coupled to the Membership API. It's also not written to be extensible. In fact, there are a lot of issues with FormsAuthentication that people would like to change, but can't. The only solution is to replace it with a new implementation, as of yet I don't know of anyone that has done that. – Erik Funkenbusch Nov 08 '11 at 21:22
  • @MystereMan Good to know. You seem to understand what I was after now, how would you have phrased the question? I'll update it so that people can find this answer easier. – Jeremy Holovacs Nov 08 '11 at 21:25
  • @JeremyHolovacs - Perhaps something like "How can I extend FormsAuthentication to update the LastActivity Membership field on page request" – Erik Funkenbusch Nov 08 '11 at 21:28
  • Well that's a bit more specific than I want, but I did update it to (hopefully) make it clearer to people. – Jeremy Holovacs Nov 08 '11 at 22:25