问题
I updated the Owin nuget packages from 3.0.0 to 3.0.1 in my WebApi projects, but after the update all the user tokens that were generated by old version, and saved on the client side stopped working with new deployment.
Is there a way to keep the old user tokens working with new version, as otherwise all the users will need to log into the system again to get new access token, which I want to avoid.
回答1:
The incompatibility between 3.0.0 and 3.0.1 is due to a bug in the 3.0.0 version of the Microsoft.Owin.Security.DataHandler.Serializer.TokenSerializer
class. This class has a private constant, FormatVersion
, which indicates the version of the format of the token. The value of this is checked in TokenSerializer.Read()
, and any token that doesn’t have a matching format version is rejected.
In version 2.x of the framework the value of FormatVersion
is 2. The format of tokens issued by the framework changed between version 2.x and 3.0.0, but it appears that Microsoft forgot to update the value of FormatVersion
. They finally updated it in 3.0.1, but of course that results in tokens issued in 3.0.0 being rejected in 3.0.1, as FormatVersion
no longer matches.
You can see the discussion about the change in format between 2.x and 3.0.0 at https://katanaproject.codeplex.com/workitem/347, and you can see the commit which broke the compatibility between 3.0.0 and 3.0.1 at https://katanaproject.codeplex.com/SourceControl/changeset/b18d18b2c9b6ebccf9e26311c74cd7896d4a7824.
The good news is that there doesn’t seem to be any other major difference in the security implementation between 3.0.0 and 3.0.1, and it appears there is a way to get this all working again. The Katana project is open source, and so you can build your own version of 3.0.1 which works around the bug. The change you’ll want to make is in TokenSerializer.Read()
, so that tokens are accepted if their version is 2 or 3.
What makes this a bit trickier is that the Microsoft.Owin packages are strongly named, and so anything referencing them will also need to be updated to explicitly reference your custom builds. So, you really only want custom builds of the Microsoft.Owin.* libraries that are directly affected by your change to TokenSerializer, or else you’ll give yourself lots of unnecessary work. In my case, I found that the libraries I really cared about were Microsoft.Owin.Security
, Microsoft.Owin.Security.OAuth
and Microsoft.Owin.Security.Jwt
. In particular, you'll want to avoid a custom build of Microsoft.Owin
as other libraries are dependent on that.
In my case, I found that I could get this all working with the following changes in the Katana solution (my fork is at https://katanaproject.codeplex.com/SourceControl/network/forks/binarymash/katanaproject?branch=FixCompatabilityWith3.0.0):
- Unload the
Microsoft.Owin
project from the solution - For every project that referenced
Microsoft.Owin
, modify it to pull the official 3.0.1 build ofMicrosoft.Owin
from Nuget - Build the solution.
- Take the customised dlls for
Microsoft.Owin.Security
,Microsoft.Owin.Security.OAuth
andMicrosoft.Owin.Security.Jwt
and use them in my own projects (and any other libraries I use in my own projects that also have these dependencies, for exampleIdentityServer3.AccessTokenValidation
) to replace the official 3.0.1 packages.
So, tokens I issued in 3.0.0 can now be authenticated in code using my custom 3.0.1 build. I don't want to keep my custom builds in my code permanently; I plan to update the token issuer from 3.0.0 to 3.0.1, at which point I will also revert back to the official 3.0.1 builds.
Your mileage may vary, and I don't accept any responsibility for the worthiness of this solution or anything that might happen if you use it ;)
回答2:
I ran into the same problem today during an upgrade.
In my case, I am only using the TicketSerializer. Fortunately for me, DataSerializers.Ticket property has a public setter which allows me to just swap out the component.
- copied ticket serializer from v2.0.1 into my solution as a fallback serializer
- wrote a new IDataSerializer which serializes using the new ticket serializer (3.0.1), attempts to deserialize using the new serializer and falls back to v2.1.0 serializer.
After a while (once all v2 tokens have expired) I should be able to swap it all back to v3.0.1 serializer.
Yet to be tested fully but seems to be fine so far. Hope this helps.
来源:https://stackoverflow.com/questions/30074563/old-tokens-stopped-working-after-updating-owin-from-3-0-0-to-3-0-1