WCF over net.tcp with token authentication, loses Claims between TokenHandler and AuthorisationManager -
we using custom binding in wcf authenticate using security token (saml). finding getting server-side , seeing tokenhandler (derived saml11securitytokenhandler) correctly process , authorise token return new claimsidentity.
however, when processing calls on authorisationmanager.checkaccesscore (derived identitymodelserviceauthorizationmanager), operationcontext.servicesecuritycontext.primaryidentity genericidentity nothing populated.
we have http implementation of binding below similar, , workd fine, can see token being validated , claimsidentity being returned, observe authorisationmanager processing same identity , allowing them through.
the nettcp binding code based 1 , looks this:
/// <summary> /// nettcp binding supports saml token being passed /// </summary> public class samlnettcpbinding : custombinding { private readonly tcptransportbindingelement _transportbindingelement; private readonly binarymessageencodingbindingelement _encodingbindingelement; // private readonly securitybindingelement _securitybindingelement; /// <summary> /// initializes new instance of <see cref="samlnettcpbinding"/> class. /// </summary> public samlnettcpbinding() { issueraddress = "http://www.myissueraddress.com/"; _transportbindingelement = new tcptransportbindingelement() { transfermode = transfermode.streamed, portsharingenabled = true }; _encodingbindingelement = new binarymessageencodingbindingelement(); } /// <summary> /// returns generic collection of binding elements custom binding. /// </summary> /// <returns> /// <see cref="t:system.collections.generic.icollection`1" /> object of type <see cref="t:system.servicemodel.channels.bindingelement" /> contains binding elements custom binding. /// </returns> public override bindingelementcollection createbindingelements() { return new bindingelementcollection() { new transactionflowbindingelement(transactionprotocol.wsatomictransactionoctober2004), createsecuritybindingelement(), new sslstreamsecuritybindingelement(), _encodingbindingelement, _transportbindingelement }; } /// <summary> /// provide definition scheme. /// </summary> /// <returns>the uri scheme transport used custom binding; or empty string if there no transport (<see cref="t:system.servicemodel.channels.transportbindingelement" /> null).</returns> public override string scheme { { return "net.tcp"; } } /// <summary> /// gets or sets issuer address. /// </summary> /// <value> /// issuer address. /// </value> public string issueraddress { get; set; } /// <summary> /// create client side binding certificate. /// </summary> /// <returns>a security binding element</returns> private securitybindingelement createsecuritybindingelement() { var protectionparameters = new x509securitytokenparameters( x509keyidentifierclausetype.thumbprint, securitytokeninclusionmode.alwaystorecipient); // configure token issuance parameters. var parameters = new issuedsecuritytokenparameters( securitytokentypes.oasiswsssaml11tokenprofile11, new endpointaddress(issueraddress), new basichttpbinding()) { keytype = system.identitymodel.tokens.securitykeytype.bearerkey, inclusionmode = securitytokeninclusionmode.alwaystorecipient }; var element = securitybindingelement.createissuedtokenovertransportbindingelement(parameters); element.messagesecurityversion = messagesecurityversion.wssecurity11wstrust13wssecureconversation13wssecuritypolicy12basicsecurityprofile10; element.endpointsupportingtokenparameters.endorsing.add(protectionparameters); return element; } } any ideas or suggestions appreciated. due .net plumbing handling lot of orchestration - it's difficult figure identity being lost. i'm confident system.servicemodel losing somewhere, what's unlcear why net.tcp transport causes , http doesn't.
thanks
(for info of readers, know chubby arse , have discussed offline including sharing additional code i'm posting can here else may hit same problem)
servicesecuritycontext.primaryidentity return claimsidentity if 1 in scope. if there more 1 identities present, cannot identify primary , generic identity returned.
in scenario, have 2 identities in context: claims identity saml token , 1 representing client certificate attached caller, required net.tcp not basichttp authentication purposes. in order access claimsidentity need update claimsserviceauthorisationmanager follows:
var identity = securitycontext.primaryidentity iclaimsidentity; if (identity == null) { // if there more 1 identity, example if there certificate primaryidentity null. if (securitycontext.authorizationcontext.properties.containskey("principal")) { var principal = securitycontext.authorizationcontext.properties["principal"] iclaimsprincipal; if (principal != null) { identity = principal.identity iclaimsidentity; } } if (identity == null) { throw new invalidoperationexception("primaryidentity identity not iclaimsidentity"); } }
Comments
Post a Comment