2013-05-01 3 views
1

Мне нужно создать и выдать токен клиентам на основе аутентификации имени пользователя и пароля. Я пробовал несколько подходов к решению этой проблемы, но все они столкнулись с проблемами.Предоставление JWT SecurityToken клиенту WCF

Мой первый план состоял в том, чтобы реализовать WS-Trust Issue на моей конечной точке WCF. Пример, который я нашел, который сделал это использовал:

[OperationContract(Action = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", 
        ReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue")] 
Message IssueToken(Message rstMessage); 

Однако изменения в WIF в 4,5 интегрировать его в .NET Framework собственно нарушили остальную часть образца кода, чтобы преобразовать сообщение в RequestSecurityToken. Кажется, что это делает WSTrustRequestSerializer, но для этого требуется WSTrustSerializationContext, и нет небольшой информации о том, как создать или настроить этот объект контекста.

Я пробовал просто сериализовать JWT, который я хочу использовать для моего типа SecurityToken, в строку и возвращая его клиенту, но похоже, что десериализация его в SecurityToken, который может использовать WCF, потребует от меня отправки JWTSecurityToken и Обработчик на клиенте, чего я хочу избежать. Хотя привязки WS-Trust, похоже, как-то обошли это и создали GenericXmlSecurityToken, я не могу найти, как создать один из них сам.

Любые мысли о том, как сериализовать/десериализовать объекты RequestSecurityToken и RequestSecurityTokenResponse в WS-Trust или как сериализовать/десериализовать токен за пределами структуры WS-Trust? Или другие идеи?

+0

Почему так сложно - просто добавьте операцию GetToken (или что-то еще) и верните строку ... – leastprivilege

+0

Проблема в том, как взять эту строку и превратить ее в SecurityToken, чтобы перейти к CreateChannelWithIssuedToken, не отправляя токен JWT и обработчик вместе с клиентом. Предполагаете ли вы, что я просто передаю токенную строку как заголовок, затем используйте поведение, чтобы вручную обработать токен? –

ответ

3

Что я сделал: Я создал свою собственную версию ответного сообщения, в которой были бит, необходимые для создания GenericXmlSecurityToken. Это то, что обычно возвращается из WSTrustChannel, поэтому казалось, что это правильно. К счастью, большинство параметров для GenericXmlSecurityToken, обертывающих JWT, являются нулевыми; Мне нужен только сериализованный токен, сериализованный с помощью WriteToken в JWTSecurityTokenHandler в службе, и значения validFrom и validTo.

код клиента:

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<IService1>(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(); 

Соответствующие биты web.config:

Связывание:

<ws2007FederationHttpBinding> 
    <binding> 
    <security mode="TransportWithMessageCredential"> 
     <message issuedKeyType="BearerKey" establishSecurityContext="false" issuedTokenType="urn:ietf:params:oauth:token-type:jwt"/> 
    </security> 
    </binding> 
</ws2007FederationHttpBinding> 

Раздел identityModel:

<system.identityModel> 
    <identityConfiguration> 
    <audienceUris> 
     <add value="--audienceUri--"/> 
    </audienceUris> 
    <securityTokenHandlers> 
     <add type="--namespace--.CustomJWTSecurityTokenHandler, --my dll--" /> 
     <securityTokenHandlerConfiguration> 
     <certificateValidation certificateValidationMode="PeerTrust"/> 
     </securityTokenHandlerConfiguration> 
    </securityTokenHandlers> 
    <issuerNameRegistry> 
     <trustedIssuers> 
     <add name="--issuer--" thumbprint="--thumbprint--"/> 
     </trustedIssuers> 
    </issuerNameRegistry> 
    </identityConfiguration> 
</system.identityModel> 

И CustomJWTSe curityTokenHandler из этого вопроса (для моего сценария была нужна только действительная часть Issuer): How to configure MIcrosoft JWT with symmetric key?

Я не видел атрибут givenTokenType, используемый в другом месте, но я нашел, что очень важно, чтобы мой код работал. Без этого я получил эту ошибку: «MessageSecurityException: не удается найти аутентификатор токена для типа токенов« Microsoft.IdentityModel.Tokens.JWT.JWTSecurityToken ».Лексемы этого типа не могут быть приняты в соответствии с текущими настройками безопасности.»

Это может быть излишним в качестве решения, но я думаю, что это минимизирует количество пользовательского кода и централизовать его в местах, где я чувствую себя более комфортно.

Благодаря как пользователю2338856, так и наименее привилегированному для получения меня оттуда!

+0

Был поиск последних настроек, вы предоставили их! – Max

+0

Эй, Николь. Мне было немного, но я пытаюсь добиться того же и не могу заставить его работать. Я использую RTM-версию 'JwtSecurityTokenHandler', найденную в пакете' System.IdentityModel.Tokens.Jwt' NuGet. Токен распознается, но в итоге я получаю ту же ошибку, что и в [этот пост] (http://stackoverflow.com/questions/27425866/sending-jwt-token-to-wif-wcf-service). Не могли бы вы хоть как-нибудь понять? –

1

AFAIK, для этого вам понадобится WSFederationBinding. Из коробки это поддерживает только токены Saml. Чтобы он поддерживал токены Jwt, вам нужно добавить обработчик безопасности, способный обрабатывать его в конвейере WiF. К сожалению, экспериментальный обработчик из Microsoft не поддерживает этот файл конфигурации, поэтому вам нужно подклассифицировать его, чтобы вы могли указать свойства в config. В качестве альтернативы вы можете использовать обработчик ThinkTecture Jwt, который также не очень легко настроить в конфигурации. Настройка всего этого займет у вас довольно много времени, и я не знаю никаких примеров в Интернете, которые это делают.

Смежные вопросы