locked
Changes to GenericPrincipal in .NET Framework 4.5 RRS feed

  • Question

  • I've recently installed .NET Framework 4.5 on my machine.  I have a ASP.NET MVC 3 application running on my machine and after making this change some features of that application does not work.  My application is compiled with .NET Framework 4.0 (in VS 2010).  My application crashes due to changes made in ASP.NET Framework 4.5 in the System.Security.Principal.GenericPrincipal class.  This class used to implement the IPrincipal interface, but now with .NET Framework 4.5 it implements ClaimsPrincipal.  Now when I try to cast HttpContext.Current.User to a GenericPrincipal object I get a the following error:

    [System.InvalidCastException] = {"Unable to cast object of type 'System.Security.Principal.GenericPrincipal' to type 'DenaliSecurity.DenaliPrincipal'."}

    FYI DenaliSecurity.DenaliPrincipal is a class which implements to IPrincipal interface.

    I understand that .NET Framework 4.5 is installed on top of .NET Framework 4.0.  However, I would expect that if my target version is 4.0, then my 4.0 code should work regardless.

    So my questions are:

    1) Why does my 4.0 code not work now that I have installed 4.5?

    2) How can I get around this issue?  Are there any configuration changes or code changes I need to make to get my application to work on a machine with .NET Framework 4.5 installed?

    Wednesday, September 5, 2012 10:39 PM

Answers

  • .NET 4.5 is an in-place upgrade of .NET 4 - so when you install it, it (subtly) changes the framework installation on that system.

    1) There is a long list of published API changes and their consequences, including some breaking changes, here: http://msdn.microsoft.com/en-us/library/hh367887.aspx#asp

    2) You should probably rework the code so that it's compliant with 4.5.  This will allow it to work on both.

    Note that GenericPrinciple derives from ClaimsPrinciple - so it still indirectly implements IPrinciple: http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.aspx  Just because both types implement the interface doesn't mean you can cast between them - the cast should fail in both 4.0 and 4.5.  You'd need to cast to the interface itself for this to work...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Mike Feng Thursday, September 6, 2012 10:24 AM
    • Marked as answer by Reed Copsey, JrMVP Monday, September 17, 2012 3:45 PM
    Wednesday, September 5, 2012 11:03 PM
  • Thank you for the information.  We finally discovered what was wrong.  The issue ended up being unrelated to the casting issue I originally described.  The root cause to the casting exception we were receiving was due to where we were setting up Principal object and setting it to HttpContext.Current.User.  We originally had this logic as part of the BeginRequest event, which seemed to work fine in 4.0 and earlier.  Unfortunately this was the incorrect way of doing things and broke when 4.5 was installed.

    So, the fix was to setup the Principal object during the AuthenticateRequest event, which has resolved our issue.  Now the HttpContext.Current.User is returning the expected Principal object when requested.

    Wednesday, September 12, 2012 9:51 PM

All replies

  • .NET 4.5 is an in-place upgrade of .NET 4 - so when you install it, it (subtly) changes the framework installation on that system.

    1) There is a long list of published API changes and their consequences, including some breaking changes, here: http://msdn.microsoft.com/en-us/library/hh367887.aspx#asp

    2) You should probably rework the code so that it's compliant with 4.5.  This will allow it to work on both.

    Note that GenericPrinciple derives from ClaimsPrinciple - so it still indirectly implements IPrinciple: http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.aspx  Just because both types implement the interface doesn't mean you can cast between them - the cast should fail in both 4.0 and 4.5.  You'd need to cast to the interface itself for this to work...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Mike Feng Thursday, September 6, 2012 10:24 AM
    • Marked as answer by Reed Copsey, JrMVP Monday, September 17, 2012 3:45 PM
    Wednesday, September 5, 2012 11:03 PM
  • Thank you for the information.  We finally discovered what was wrong.  The issue ended up being unrelated to the casting issue I originally described.  The root cause to the casting exception we were receiving was due to where we were setting up Principal object and setting it to HttpContext.Current.User.  We originally had this logic as part of the BeginRequest event, which seemed to work fine in 4.0 and earlier.  Unfortunately this was the incorrect way of doing things and broke when 4.5 was installed.

    So, the fix was to setup the Principal object during the AuthenticateRequest event, which has resolved our issue.  Now the HttpContext.Current.User is returning the expected Principal object when requested.

    Wednesday, September 12, 2012 9:51 PM
  • I think I have the same error. We migrate a .net 1.1 to 4.5. today we started to have multiple of invalid cast GenericPrincipal' to MyGenericPrincipal.

    The error seems to be when I try a cast

    CType(HttpContext.Current.User, ABC.ABCPrincipal)

    In the Application_AuthenticateRequest, I set user

    Me.Context.User = ABC.ABCUtils.GetABCPrincipal(Me.Context)
    

    We already do it. what did you do? (if you remember, was years ago)
    Monday, November 2, 2015 8:34 PM