| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Globalization;
- using System.IdentityModel.Policy;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Reflection;
- using System.ServiceModel;
- using System.ServiceModel.Security.Tokens;
- using SysClaim = System.IdentityModel.Claims.Claim;
- using SystemAuthorizationContext = System.IdentityModel.Policy.AuthorizationContext;
- using System.Security.Claims;
- namespace System.ServiceModel.Security
- {
- /// <summary>
- /// Wraps a SessionSecurityTokenHandler. Delegates the token authentication call to
- /// this wrapped tokenAuthenticator. Wraps the returned ClaimsIdentities into
- /// an IAuthorizationPolicy. This class is wired into WCF and actually receives
- /// SecurityContextSecurityTokens which are then wrapped into SessionSecurityTokens for
- /// validation.
- /// </summary>
- internal class WrappedSessionSecurityTokenAuthenticator : SecurityTokenAuthenticator, IIssuanceSecurityTokenAuthenticator, ICommunicationObject
- {
- SessionSecurityTokenHandler _sessionTokenHandler;
- IIssuanceSecurityTokenAuthenticator _issuanceSecurityTokenAuthenticator;
- ICommunicationObject _communicationObject;
- SctClaimsHandler _sctClaimsHandler;
- ExceptionMapper _exceptionMapper;
- /// <summary>
- /// Initializes an instance of <see cref="WrappedRsaSecurityTokenAuthenticator"/>
- /// </summary>
- /// <param name="sessionTokenHandler">The sessionTokenHandler to wrap</param>
- /// <param name="wcfSessionAuthenticator">The wcf SessionTokenAuthenticator.</param>
- /// <param name="sctClaimsHandler">Handler that converts WCF generated IAuthorizationPolicy to <see cref="AuthorizationPolicy"/></param>
- /// <param name="exceptionMapper">Converts token validation exception to SOAP faults.</param>
- public WrappedSessionSecurityTokenAuthenticator( SessionSecurityTokenHandler sessionTokenHandler,
- SecurityTokenAuthenticator wcfSessionAuthenticator,
- SctClaimsHandler sctClaimsHandler,
- ExceptionMapper exceptionMapper )
- : base()
- {
- if ( sessionTokenHandler == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "sessionTokenHandler" );
- }
- if ( wcfSessionAuthenticator == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "wcfSessionAuthenticator" );
- }
- if ( sctClaimsHandler == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "sctClaimsHandler" );
- }
- if ( exceptionMapper == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "exceptionMapper" );
- }
- _issuanceSecurityTokenAuthenticator = wcfSessionAuthenticator as IIssuanceSecurityTokenAuthenticator;
- if ( _issuanceSecurityTokenAuthenticator == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID4244 ) );
- }
- _communicationObject = wcfSessionAuthenticator as ICommunicationObject;
- if ( _communicationObject == null )
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperInvalidOperation( SR.GetString( SR.ID4245 ) );
- }
- _sessionTokenHandler = sessionTokenHandler;
- _sctClaimsHandler = sctClaimsHandler;
- _exceptionMapper = exceptionMapper;
- }
- /// <summary>
- /// Validates the token using the wrapped token handler and generates IAuthorizationPolicy
- /// wrapping the returned ClaimsIdentities.
- /// </summary>
- /// <param name="token">Token to be validated. This is always a SecurityContextSecurityToken.</param>
- /// <returns>Read-only collection of IAuthorizationPolicy</returns>
- protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore( SecurityToken token )
- {
- SecurityContextSecurityToken sct = token as SecurityContextSecurityToken;
- SessionSecurityToken sessionToken = SecurityContextSecurityTokenHelper.ConvertSctToSessionToken( sct );
- IEnumerable<ClaimsIdentity> identities = null;
- try
- {
- identities = _sessionTokenHandler.ValidateToken(sessionToken, _sctClaimsHandler.EndpointId);
- }
- catch (Exception ex)
- {
- if (!_exceptionMapper.HandleSecurityTokenProcessingException(ex))
- {
- throw;
- }
- }
- return new List<IAuthorizationPolicy>(new AuthorizationPolicy[] { new AuthorizationPolicy(identities) }).AsReadOnly();
- }
- protected override bool CanValidateTokenCore( SecurityToken token )
- {
- return ( token is SecurityContextSecurityToken );
- }
- #region IIssuanceSecurityTokenAuthenticator Members
- public IssuedSecurityTokenHandler IssuedSecurityTokenHandler
- {
- get
- {
- return _issuanceSecurityTokenAuthenticator.IssuedSecurityTokenHandler;
- }
- set
- {
- _issuanceSecurityTokenAuthenticator.IssuedSecurityTokenHandler = value;
- }
- }
- public RenewedSecurityTokenHandler RenewedSecurityTokenHandler
- {
- get
- {
- return _issuanceSecurityTokenAuthenticator.RenewedSecurityTokenHandler;
- }
- set
- {
- _issuanceSecurityTokenAuthenticator.RenewedSecurityTokenHandler = value;
- }
- }
- #endregion
- #region ICommunicationObject Members
- // all these methods are passthroughs
- public void Abort()
- {
- _communicationObject.Abort();
- }
- public System.IAsyncResult BeginClose( System.TimeSpan timeout, System.AsyncCallback callback, object state )
- {
- return _communicationObject.BeginClose( timeout, callback, state );
- }
- public System.IAsyncResult BeginClose( System.AsyncCallback callback, object state )
- {
- return _communicationObject.BeginClose( callback, state );
- }
- public System.IAsyncResult BeginOpen( System.TimeSpan timeout, System.AsyncCallback callback, object state )
- {
- return _communicationObject.BeginOpen( timeout, callback, state );
- }
- public System.IAsyncResult BeginOpen( System.AsyncCallback callback, object state )
- {
- return _communicationObject.BeginOpen( callback, state );
- }
- public void Close( System.TimeSpan timeout )
- {
- _communicationObject.Close( timeout );
- }
- public void Close()
- {
- _communicationObject.Close();
- }
- public event System.EventHandler Closed
- {
- add { _communicationObject.Closed += value; }
- remove { _communicationObject.Closed -= value; }
- }
- public event System.EventHandler Closing
- {
- add { _communicationObject.Closing += value; }
- remove { _communicationObject.Closing -= value; }
- }
- public void EndClose( System.IAsyncResult result )
- {
- _communicationObject.EndClose( result );
- }
- public void EndOpen( System.IAsyncResult result )
- {
- _communicationObject.EndOpen( result );
- }
- public event System.EventHandler Faulted
- {
- add { _communicationObject.Faulted += value; }
- remove { _communicationObject.Faulted -= value; }
- }
- public void Open( System.TimeSpan timeout )
- {
- _communicationObject.Open( timeout );
- }
- public void Open()
- {
- _communicationObject.Open();
- }
- public event System.EventHandler Opened
- {
- add { _communicationObject.Opened += value; }
- remove { _communicationObject.Opened -= value; }
- }
- public event System.EventHandler Opening
- {
- add { _communicationObject.Opening += value; }
- remove { _communicationObject.Opening -= value; }
- }
- public CommunicationState State
- {
- get { return _communicationObject.State; }
- }
- #endregion
- }
- /// <summary>
- /// Defines a SecurityStateEncoder whose Encode and Decode operations are
- /// a no-op. This class is used to null WCF SecurityContextToken creation
- /// code to skip any encryption and decryption cost. When SessionSecurityTokenHandler
- /// is being used we will use our own EncryptionTransform and ignore the WCF
- /// generated cookie.
- /// </summary>
- internal class NoOpSecurityStateEncoder : SecurityStateEncoder
- {
- protected internal override byte[] EncodeSecurityState( byte[] data )
- {
- return data;
- }
- protected internal override byte[] DecodeSecurityState( byte[] data )
- {
- return data;
- }
- }
- }
|