Comments (7)
Can you share the Fiddler trace file?
Note WsFed is not appropriate for most API usage, JwtBearer is much better here.
from security.
@MSAppsDev fyi your code sample works just fine for me on ADFS 2016.
from security.
@rasitha1, i am trying it on adfs 2012.
from security.
unfortunately i cannot use ad fs 2016, our Ops team setup ws-federation sign-in emitting jwt on ad fs 2012. Here is the response i am getting after entering credentials in login page.
<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:Lifetime><wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-26T18:41:58.232Z</wsu:Created>
<wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-26T20:41:58.232Z</wsu:Expires></t:Lifetime>
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">wsa:Addressurn:adfs:federation:XXXX:Test</wsa:Address></wsa:EndpointReference></wsp:AppliesTo>
<t:RequestedSecurityToken>
<wsse:BinarySecurityToken wsu:Id="_62879890-6cee-4ca5-a679-8ef96c945f23-AF7CC0FC9150402EBC2B87449ECC9273" ValueType="urn:ietf:params:oauth:token-type:jwt"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUlzSW5nMWRDSTZJamN5Y0ZJMVMzZ3hTamxaYTBaRFRUTmlNbkpKT1ZGd04xbFVaeUo5LmV5SmhkV1FpT2lKMWNtNDZZV1JtY3pwbVpXUmxjbUYwYVc5dU9rRlVWRk02VkdWemRDSXNJbWx6Y3lJNkltaDBkSEE2THk5emMyOXNiMmRwYmkxemRHY3VjSFZpYkdsNExtTnZiUzloWkdaekwzTmxjblpwWTJWekwzUnlkWE4wSWl3aWFXRjBJam94TlRRek1qVTNOekU0TENKbGVIQWlPakUxTkRNeU5qUTVNVGdzSW5kcGJtRmpZMjkxYm5SdVlXMWxJam9pVUZWQ1RFbFlRVkJRVkZOVVhGeDVZWFIwYzNOd2N5SXNJblZ3YmlJNklubGhkSFJ6YzNCelFIQjFZbXhwZUdGd2NIUnpkQzVqYjIwaUxDSm5hWFpsYmw5dVlXMWxJam9pV1VGVVZGTlRVRk1pTENKbGJYQnNiM2xsWlVsRUlqb2lXVUZVVkZOVFVGTWlMQ0p6ZFdJaU9pSjVZWFIwYzNOd2MwQndkV0pzYVhoaGNIQjBjM1F1WTI5dElpd2ljbTlzWlNJNklsQnliMlJUZFhCd2IzSjBJaXdpWVhWMGFHMWxkR2h2WkNJNkluVnlianB2WVhOcGN6cHVZVzFsY3pwMFl6cFRRVTFNT2pJdU1EcGhZenBqYkdGemMyVnpPbEJoYzNOM2IzSmtVSEp2ZEdWamRHVmtWSEpoYm5Od2IzSjBJaXdpWVhWMGFGOTBhVzFsSWpvaU1qQXhPQzB4TVMweU5sUXhPRG8wTVRvMU5pNDNOREZhSWl3aWRtVnlJam9pTVM0d0luMC5ySk9WSnFlM3V1V2FtV0p6bk5sNVFfbGRhMnc2bGRtUUozZnNfRk9wM1dDSnpRVlVzbTdOSGR6T3dQZU5lWlFya3czajZDdGktVjlEbk1fT2JncEQxRUh1YXlTZ0R5TzZ5RU8xT0JDZnp4UUd1enRBNjNZVlFWd0czWnJvd3BnanV5WVBBVTZoMXMxZ1hnd2dBbUhtNTcweE91ZFk0Rzhxb1BIa08wZG95SHlUeUl6R2dZR0VhMFYxX0NYU0piV1RyWDBZMHduSmZLbEQzQmVTX1RRY1JMbUpvMktFbzhQYnBVV2g3bDlqdE9jNUplV0pKUUNjRldlOEUwOVltUjNITHJzMllvVUZJYllaWEFwZ2J6d3NXSWlMTFRLLXNBLUQtZzBQZFN2N2ozNjFVUDVBZWY5SEhQelRuWVJTeGYwRjluSUNHUm9kVUVYbjRWbUg1MGxkVkE=
</wsse:BinarySecurityToken>
</t:RequestedSecurityToken>
<t:TokenType>urn:ietf:params:oauth:token-type:jwt</t:TokenType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
</t:RequestSecurityTokenResponse>
Since claims are null, it gets into loop for 6 to 8 (whatever is configured in ad fs retry) then errors out.
from security.
Looks like WsFederationOptions is initialized with Saml and JWT token handlers however that's the wrong JWT token handler for this RequestedSecurityToken
.
JwtSecurityTokenHandler
expects a plain JWT string and not this BinarySecurityToken
.
So in order to get this working you need to change ADFS (-EnableJWT $false
) and get a regular SAML assertion. Then the sign-in should work.
Does anyone know what's the point in having JwtSecurityTokenHandler
listed in WsFederationOptions
? Is there ever a case where a WS-Fed RSTR can come with RequestedSecurityToken
having a plain JWT?
It seems like a wrapper WsFedJwtSecurityTokenHandler is needed for handling urn:ietf:params:oauth:token-type:jwt
tokens which will extract the base64 JWT from the BinarySecurityToken
and then call the existing JwtSecurityTokenHandler
passing in the actual JWT.
from security.
from security.
Finally made it work, here is the custom tokenvalidator if someone needs, this parses BinarySecurityToken from Base 64.
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace XXXXX.Web
{
/// <summary>
/// Custom JWT security token validator
/// </summary>
public class WsFedTokenValidator : ISecurityTokenValidator
{
private string _jwtTokenString = null;
private JwtSecurityToken _jwt = null;
private JwtSecurityTokenHandler _jwtHandler = new JwtSecurityTokenHandler();
/// <summary>
/// Returns true if a token can be validated
/// </summary>
/// <returns>true if a token can be validated</returns>
public bool CanValidateToken => throw new NotImplementedException();
/// <summary>
/// Gets and sets the maximum size in bytes that will be processed.
/// </summary>
/// <returns>token size</returns>
public int MaximumTokenSizeInBytes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
/// <summary>
/// Read JWT token
/// </summary>
/// <param name="securityToken"></param>
/// <returns>tue in case of valid token else false</returns>
public bool CanReadToken(string securityToken)
{
bool response = false;
try
{
if (!string.IsNullOrWhiteSpace(securityToken))
{
var xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(securityToken);
if (xmlDoc != null)
{
byte[] tokenBytes = Convert.FromBase64String(xmlDoc.InnerText); //convert the Base64-encoded binary to bytes
_jwtTokenString = Encoding.UTF8.GetString(tokenBytes); //get the original base64-encoded token
if (!string.IsNullOrWhiteSpace(_jwtTokenString))
{
_jwt = _jwtHandler.ReadToken(_jwtTokenString) as JwtSecurityToken;
if (_jwt != null)
{
response = true;
}
}
}
}
return response;
}
finally
{
}
}
/// <summary>
/// Custom security token validation
/// </summary>
/// <param name="securityToken"></param>
/// <param name="validationParameters"></param>
/// <param name="validatedToken"></param>
/// <returns>claims</returns>
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
ClaimsPrincipal principal = null;
SecurityToken token = null;
try
{
if (_jwt != null)
{
principal = _jwtHandler.ValidateToken(_jwtTokenString, validationParameters, out token);
}
validatedToken = token;
return principal;
}
finally
{
}
}
}
}
from security.
Related Issues (20)
- About policy in Multiple Schemes 403 problem HOT 2
- AVRO serialization error - Could not find any matching known type for 'Newtonsoft.Json.Linq.JToken' using c# HOT 3
- How to Validate AccessToken in WebAPI core 2.0 getting from IdentityServer3 HOT 1
- Multiple refresh for authentication on server HOT 33
- Oauth MicrosoftAccount Token Request Issue HOT 6
- OAuth redirect_uri using http instead of https on Azure App Service Linux HOT 9
- Is there a way to Decrypt encrypted SAML token?? HOT 9
- Set redirect from authorization handler HOT 5
- JWT payload "unique_name" not mapped correctly HOT 2
- .
- HttpContext.SignInAsync sets null to Identity claims data HOT 3
- Handling incomplete remote signouts HOT 15
- AuthenticationProperties object is not passed to ChallengeAsync / ForbidAsync HOT 11
- [Net Core 2.0] AccessDeniedPath ignored in cookie authentication HOT 1
- Docker Swarm + nginx + WS-Federation: multiple redirection issue HOT 33
- SSO for Microsoft Outlook using auth0 HOT 6
- Redirect URI is ignored HOT 2
- Wctx parameter getting overridden, breaking functionality HOT 8
- ASP.NET Core OpenId Authentication in Container with TLS Termination in WAF HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from security.