/// <summary> /// Validates a <see cref="KerberosReceiverSecurityToken"/>. /// </summary> /// <param name="token">The <see cref="KerberosReceiverSecurityToken"/> to validate.</param> /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities contained in the token.</returns> /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception> /// <exception cref="ArgumentException">The token is not assignable from <see cref="KerberosReceiverSecurityToken"/>.</exception> /// <exception cref="InvalidOperationException">Configuration <see cref="SecurityTokenHandlerConfiguration"/>is null.</exception> /// <exception cref="InvalidOperationException">The <see cref="WindowsIdentity"/> of the <see cref="KerberosReceiverSecurityToken"/>is null.</exception> public override ReadOnlyCollection <ClaimsIdentity> ValidateToken(SecurityToken token) { if (token == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token"); } KerberosReceiverSecurityToken kerbToken = token as KerberosReceiverSecurityToken; if (kerbToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(KerberosReceiverSecurityToken))); } if (this.Configuration == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4274)); } try { if (kerbToken.WindowsIdentity == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4026)); } // KerberosReceiveSecurityToken is disposable, best to make a copy as Dispose() nulls out the WindowsIdentity. The AuthenticationType was set when the kerbToken was created. WindowsIdentity wi = new WindowsIdentity(kerbToken.WindowsIdentity.Token, kerbToken.WindowsIdentity.AuthenticationType); // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical. wi.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(DateTime.UtcNow, DateTimeFormats.Generated), ClaimValueTypes.DateTime)); wi.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Windows, ClaimValueTypes.String)); if (this.Configuration.SaveBootstrapContext) { wi.BootstrapContext = new BootstrapContext(token, this); } this.TraceTokenValidationSuccess(token); List <ClaimsIdentity> identities = new List <ClaimsIdentity>(1); identities.Add(wi); return(identities.AsReadOnly()); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } this.TraceTokenValidationFailure(token, e.Message); throw e; } }
/// <summary> /// Validates a Kerberos WSS user token. /// </summary> private SecurityToken ParseAndVerifyKerberosToken(byte[] tokenData) { XmlDocument document = new XmlDocument(); XmlNodeReader reader = null; try { document.InnerXml = new UTF8Encoding().GetString(tokenData).Trim(); reader = new XmlNodeReader(document.DocumentElement); SecurityToken securityToken = new WSSecurityTokenSerializer().ReadToken(reader, null); System.IdentityModel.Tokens.KerberosReceiverSecurityToken receiver = securityToken as KerberosReceiverSecurityToken; KerberosSecurityTokenAuthenticator authenticator = new KerberosSecurityTokenAuthenticator(); if (authenticator.CanValidateToken(receiver)) { authenticator.ValidateToken(receiver); } return(securityToken); } catch (Exception e) { // construct translation object with default text. TranslationInfo info = new TranslationInfo( "InvalidKerberosToken", "en-US", "'{0}' is not a valid Kerberos token.", document.DocumentElement.LocalName); // create an exception with a vendor defined sub-code. throw new ServiceResultException(new ServiceResult( e, StatusCodes.BadIdentityTokenRejected, "InvalidKerberosToken", Namespaces.UserAuthentication, new LocalizedText(info))); } finally { if (reader != null) { reader.Close(); } } }