Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication.WsFederation breaks with on-premise AD FS use #52099

Closed
1 task done
csowa opened this issue Nov 15, 2023 · 21 comments
Closed
1 task done

Authentication.WsFederation breaks with on-premise AD FS use #52099

csowa opened this issue Nov 15, 2023 · 21 comments
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer External This is an issue in a component not contained in this repository. It is open for tracking purposes.

Comments

@csowa
Copy link

csowa commented Nov 15, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Using Authentication.WsFederation for authentication results in error regardless of new UseSecurityTokenHandlers setting.

options.UseSecurityTokenHandlers = true;

SecurityTokenInvalidIssuerException: IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.

Expected: behavior prior to change introduced with issue 49469.

options.UseSecurityTokenHandlers = false;

XmlReadException: IDX30011: Unable to read XML. Expecting XmlReader to be at ns.element: 'urn:oasis:names:tc:SAML:2.0:assertion.Assertion', found: 'urn:oasis:names:tc:SAML:1.0:assertion.Assertion'.

Expected: to be able to handle SAML 1.0 assertion emitted by WsFed server.

Expected Behavior

options.UseSecurityTokenHandlers = true;

Expected: behavior prior to change introduced with issue 49469.

options.UseSecurityTokenHandlers = false;

Expected: to be able to handle SAML 1.0 assertion emitted by WsFed server.

Steps To Reproduce

Repro project: https://github.com/csowa/aspdotnetcore-auth-sample

Demonstrates WS-Federation issue with change introduced for #49469

Based on example at https://learn.microsoft.com/en-us/aspnet/core/security/authentication/ws-federation?view=aspnetcore-8.0#use-ws-federation-without-aspnet-core-identity

Build and run. Home page uses [Authorize] attribute, authentication begins when loading.

Dependency: ADFS server required. Server version tested: 10.0.17763.4644

Exceptions (if any)

options.UseSecurityTokenHandlers = true;

SecurityTokenInvalidIssuerException: IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.

options.UseSecurityTokenHandlers = false;

XmlReadException: IDX30011: Unable to read XML. Expecting XmlReader to be at ns.element: 'urn:oasis:names:tc:SAML:2.0:assertion.Assertion', found: 'urn:oasis:names:tc:SAML:1.0:assertion.Assertion'.

.NET Version

8.0.100

Anything else?

No response

@mkArtakMSFT
Copy link
Member

Thanks for contacting us.
Please share the full stack-trace of the error that you see.

@Tratcher Tratcher added area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer and removed area-security labels Nov 16, 2023
@csowa
Copy link
Author

csowa commented Nov 16, 2023

options.UseSecurityTokenHandlers = true;


Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login.
---> Microsoft.IdentityModel.Tokens.SecurityTokenException: No token validator or token handler was found for the given token.
---> Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuerAsync(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateSignature(SamlSecurityToken samlToken, String token, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.WsFederation.WsFederationHandler.HandleRemoteAuthenticateAsync()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.WsFederation.WsFederationHandler.HandleRemoteAuthenticateAsync()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

@csowa
Copy link
Author

csowa commented Nov 16, 2023

options.UseSecurityTokenHandlers = false;


Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login.
---> Microsoft.IdentityModel.Tokens.SecurityTokenException: No token validator or token handler was found for the given token.
---> System.AggregateException: One or more errors occurred. (IDX30011: Unable to read XML. Expecting XmlReader to be at ns.element: 'urn:oasis:names:tc:SAML:2.0:assertion.Assertion', found: 'urn:oasis:names:tc:SAML:1.0:assertion.Assertion'.) (IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.) (IDX14100: JWT is not well formed, there are no dots (.).
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.)
---> Microsoft.IdentityModel.Xml.XmlReadException: IDX30011: Unable to read XML. Expecting XmlReader to be at ns.element: 'urn:oasis:names:tc:SAML:2.0:assertion.Assertion', found: 'urn:oasis:names:tc:SAML:1.0:assertion.Assertion'.
at Microsoft.IdentityModel.Xml.XmlUtil.CheckReaderOnEntry(XmlReader reader, String element, String namespace)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAssertion(XmlReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(XmlReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(String token)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(String token, TokenValidationParameters validationParameters)
--- End of inner exception stack trace ---
---> (Inner Exception #1) Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuerAsync(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateSignature(SamlSecurityToken samlToken, String token, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(String token, TokenValidationParameters validationParameters)<---

---> (Inner Exception #2) Microsoft.IdentityModel.Tokens.SecurityTokenMalformedException: IDX14100: JWT is not well formed, there are no dots (.).
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.
---> Microsoft.IdentityModel.Tokens.SecurityTokenMalformedException: IDX14122: JWT is not a well formed JWE, there are more than four dots (.) a JWE can have at most 4 dots.
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.
at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken.ReadToken(String encodedJson)
at Microsoft.IdentityModel.JsonWebTokens.JsonWebToken..ctor(String jwtEncodedString)
at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ReadToken(String token, TokenValidationParameters validationParameters)
--- End of inner exception stack trace ---<---

--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.WsFederation.WsFederationHandler.HandleRemoteAuthenticateAsync()
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

@Hakon
Copy link

Hakon commented Nov 17, 2023

We have encountered this issue as well and implemented a workaround.

This may be an issue with a difference in how JsonWebTokenHandler and SamlSecurityTokenHandler handles configuration fetching from ConfigurationManager. I have reported this issue to Microsoft.IdentityModel here: AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet#2406

The JsonWebTokenHandler fetches BaseConfiguration from the ConfigurationManager when validating a token, the Saml*SecurityTokenHandler does not. This change a56e968#diff-42233637069e62d711d83e163c06bbf11849c4acb594daaf5587697c3ef0789fL99 changed configuration fetching so that this now is delegated to the TokenHandler when using the default ConfigurationManager or StaticConfigurationManager (inherits from BaseConfigurationManager). While this works for JsonWebTokenHandler, the SAML handlers is not compatible.

@csowa
Copy link
Author

csowa commented Nov 20, 2023

Received the following response via email, does not appear here.


From: Stephen Halter
Sent: Monday, November 20, 2023 9:49 AM
To: dotnet/aspnetcore
Cc: Chris Sowa; Author
Subject: Re: [dotnet/aspnetcore] Authentication.WsFederation breaks with on-premise AD FS use (Issue #52099)

It's undocumented breaking change.
We did make a breaking change announcement for the switch from JwtSecurityToken and JwtTokenValidators to JsonWebToken and TokenHandler in .NET 8 preview 7. https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/8.0/securitytoken-events

We recommend updating your code to utilize the newer, more-optimized types. But if that's not possible, you can set WsFederationOptions.UseSecurityTokenHandlers = true which is the second option listed in the "Recommended action" section of the announcement.
If there's something that is no longer possible with the new types, please file an issue at https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet. If you have suggestions for how to improve the breaking change announcement, you can suggest edits at https://github.com/dotnet/docs/blob/main/docs/core/compatibility/aspnet-core/8.0/securitytoken-events.md

@csowa
Copy link
Author

csowa commented Nov 20, 2023

Thank you for your response. I am aware of the breaking change as described. Unfortunately, that is not the issue here.
I am attempting to use an ASP.NET Core component, and it breaks regardless of UseSecurityTokenHandlers setting. Please see the provided repro app.

I can confirm the issue noted above #52099 (comment), and I can work around the initialization problem related to that which was introduced in the associated ASP.NET Core change to the WsFederation component.

While that initialization issue may have a root cause deeper in the architecture and in a separate project, the issue is exposed in a component from this project.

There is a separate issue in the new token handler in that it does not appear to handle WS-Fed tokens properly. But again, that is internal to the ASP.NET Core component implementation in its choice of relying on other projects.

I am not using the token handlers directly, there is nothing in the code or the sample app to be switched.

It appears that ASP.NET Core's Authentication.WsFederation component has relied internally on one or more broken components from other project(s).

I would expect that such internal issues between projects would be addressed by the involved projects' members.

To reiterate: this is not a question about the breaking change that was noted, it's an issue with the component not working as documented, requiring user space work arounds.

@OttoG
Copy link

OttoG commented Nov 20, 2023

Hi, I can confirm what @csowa assumes, that this is not a matter of the state of the UseSecurityTokenHandlers setting or in any way specifically related to the breaking change announced for Preview 7 that prompted the introduction of that setting, as mentioned above.

That change relates to the use of JWT tokens (and handling them with one class or the other), but the error messages in the bug report clearly indicate that @csowa uses SAML tokens, which are handled by completely different classes.

@Hakon has, as far as I can tell, correctly diagnosed the problem and has also published a great workaround in this issue: AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet#2406

The error message in this bug report indicates that the workaround should be applicable as-is, but users who get a SAML 2.0 version token may need to subclass Saml2SecurityTokenHandler instead of SamlSecurityTokenHandler.

As @csowa writes, this is fine for those of us who are in control of the code that configures WsFederation, but if that code resides in a separate component that cannot be easily modified, it of course becomes a direct obstacle to adoption .NET 8.0.

@Hakon
Copy link

Hakon commented Nov 21, 2023

The error message in this bug report indicates that the workaround should be applicable as-is, but users who get a SAML 2.0 version token may need to subclass Saml2SecurityTokenHandler instead of SamlSecurityTokenHandler.

This is correct. It was not intended as a general fix for everyone but rather a hint at how to work around the problem. I am working on a proper fix in IdentityModel.

@brentschmaltz
Copy link
Contributor

@Hakon @OttoG @csowa @halter73 the workaround is great and can be used until we get the fix into IdentityModel.
Please make sure to call TokenValidationParameters.Clone() before modifying and calling ValidateTokenAsync(...) as TokenValidationParameters can persist across http requests.

@Hakon
Copy link

Hakon commented Dec 6, 2023

Thank you for the warning. I have submitted a fix to IdentityModel.

@arknu
Copy link

arknu commented Dec 22, 2023

Just hit this as well. This is a pretty big breaking change to be undocumented! And how come this has not been fixed? It completely breaks ADFS Integration.

Thanks for the workaround, @Hakon! It works great.

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 6, 2024
@wtgodbe wtgodbe removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Feb 13, 2024
@dotnet dotnet deleted a comment from dotnet-policy-service bot Feb 13, 2024
@dotnet dotnet deleted a comment from dotnet-policy-service bot Feb 13, 2024
@SimonCropp
Copy link
Contributor

@Hakon

Thank you for the warning. I have submitted a fix to IdentityModel.

can you link to the fix. did it make it into net8?

@halter73 halter73 added External This is an issue in a component not contained in this repository. It is open for tracking purposes. investigate and removed investigate labels Feb 27, 2024
@halter73 halter73 removed their assignment Feb 27, 2024
@halter73
Copy link
Member

can you link to the fix. did it make it into net8?

Not yet. The PR to fix it is still open at AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet#2412.

@iSatishYadav
Copy link

Stumbled upon this after spending afternoon. The workaround works as claimed. But a major breaking change.

@guillaume86
Copy link

Yes some regression tests would be welcome for components this sensitive.

@MatiasEnrique
Copy link

MatiasEnrique commented Mar 9, 2024

Had it fixed after replacing:
image
for:
image

@mkArtakMSFT
Copy link
Member

Closing as the updated packages from the Microsoft.IdentityModel.* version 7.4.1 have shipped now, which includes the fix.

@hheexx
Copy link

hheexx commented Mar 15, 2024

Will next patch version of WsFederation depend on fixed versions of IdentityModel?

@csowa
Copy link
Author

csowa commented Mar 15, 2024

Will next patch version of WsFederation depend on fixed versions of IdentityModel?

That is the bug covered by this issue. This appears to have been prematurely closed, pending resolution / confirmation of WsFederation's dependency.

@pcibraro
Copy link

Microsoft.AspNetCore.Authentication.WsFederation has not been updated to reference 7.4.1, which is the one that contains the fix. The latest version 8.0.4 still references to 7.1.2. Do you know if there is any plan to get that updated ? Thanks

@jjacobson
Copy link

@mkArtakMSFT This issue was specifically for Authentication.WsFederation breaking. Despite the fix to Microsoft.IdentityModel, Authentication.WsFederation still has not been updated to reference the fixed version, and thus the issue raised by this ticket still exists. This was closed prematurely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-auth Includes: Authn, Authz, OAuth, OIDC, Bearer External This is an issue in a component not contained in this repository. It is open for tracking purposes.
Projects
None yet
Development

No branches or pull requests