Delivering a JWT SecurityToken to a WCF client

后端 未结 2 781
野性不改
野性不改 2021-01-24 03:29

I need to generate and issue a token to clients based on username/password authentication. I\'ve tried several approaches to solving this problem, but all of them have run into

2条回答
  •  长发绾君心
    2021-01-24 04:05

    What I did was this: I created my own version of a response message which had the bits I needed to create a GenericXmlSecurityToken. This is what's generally returned from a WSTrustChannel, so it seemed like the right thing to do. Thankfully, most of the parameters for a GenericXmlSecurityToken wrapping a JWT are null; I only needed the serialized token, serialized with WriteToken on the JWTSecurityTokenHandler in the service, and the validFrom and validTo values.

    Client code:

    XmlElement element = document.CreateElement("wsse", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    element.SetAttribute("ValueType", "urn:ietf:params:oauth:token-type:jwt");
    element.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
    UTF8Encoding encoding = new UTF8Encoding();
    element.InnerText = Convert.ToBase64String(encoding.GetBytes(jwtToken));
    
    GenericXmlSecurityToken token = new GenericXmlSecurityToken(
        element,
        null,
        validFrom,
        validTo,
        null,
        null,
        null);
    
    var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
    binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
    binding.Security.Message.EstablishSecurityContext = false;
    binding.Security.Message.IssuedTokenType = "urn:ietf:params:oauth:token-type:jwt";
    
    var factory2 = new ChannelFactory(binding, new EndpointAddress("https://localhost:44300/Service1.svc"));
    factory2.Credentials.SupportInteractive = false;
    factory2.Credentials.UseIdentityConfiguration = true;
    
    var proxy = factory2.CreateChannelWithIssuedToken(token);
    
    var info = proxy.DoWork();
    

    Relevant bits of the web.config:

    The binding:

    
      
        
          
        
      
    
    

    The identityModel section:

    
      
        
          
        
        
          
          
            
          
        
        
          
            
          
        
      
    
    

    And the CustomJWTSecurityTokenHandler from this question (only the validIssuer part was required for my scenario): How to configure MIcrosoft JWT with symmetric key?

    I haven't seen the issuedTokenType attribute used elsewhere, but I found it was essential to getting my code to work. Without it, I got this error: "MessageSecurityException: Cannot find a token authenticator for the 'Microsoft.IdentityModel.Tokens.JWT.JWTSecurityToken' token type. Tokens of that type cannot be accepted according to current security settings."

    This might be overkill as a solution, but I think it minimizes the amount of custom code and centralizes it in places I feel more comfortable with.

    Thanks to both user2338856 and leastprivilege for getting me partway there!

提交回复
热议问题