/// <summary> /// Acquires Holder of Key Token by Username and Password. /// HoK token issuance requires Clients to /// 1. Sign AcquireToken Request with the private key of their Signing Certificate /// 2. To present the public key of the Signing Certificate to the Authorization Server in the AcquireToken Request /// 3. Authorization Server validate the request signature is signed with the private key of the presented public key /// This way Authorization Server ensures request is not modified and the client has the private key corresponding the public key. /// HoK tokens are valid for longer period of time compared to the bearer tokens. /// HoK tokens can be used to acquire baerer tokens on behalf of the subject. This way servers /// can keep HoK and issue Bearer Tokens with which to present the Subject to other services. /// 4. HoK token can be delegetable to delegate authorization to other services to act on behalf of the subject. /// User authorizes one service to act on his behalf against another server /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="signingCertitificate">The Signing Certificate of the client that will be used to sign the request and present the public key to the Authorization Server</param> /// <param name="actAsSamlToken">Act As Saml token</param> /// <returns>Raw XML representation of the SAML 2.0 HoK Token</returns> public XmlElement IssueActAsHoKTokenByUserCredential( string username, SecureString password, X509Certificate2 signingCertitificate, XmlElement actAsSamlToken) { if (username == null) { throw new ArgumentNullException("username"); } // SAML Token Request var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey", ActAs = actAsSamlToken, DelegatableSpecified = true, Delegatable = true, Renewing = new RenewingType { AllowSpecified = true, Allow = true, OKSpecified = true, OK = true }, SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" }; // Security Token Request Authorization Header var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { User = username, Password = password, // Certificate which will be used by the Authorization Server to validate the signature of the request ClientCertificate = signingCertitificate }, // This Key will be used to sign the request SigningKey = signingCertitificate.PrivateKey } }; // Request Authorization Server to Issue HoK Token IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); // Extract the Raw XML Token from the Authorizations Server's Response return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }
/// <summary> /// Acquires Bearer Token by Username and Password. /// Bearer Token is short lived token that can be presented to the resource server /// to authorize the request to access the resource. Typically used by /// clients to authorize their requests to the server. /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <returns>Raw XML representation of the SAML 2.0 Bearer Token</returns> public XmlElement IssueBearerTokenByUserCredential( string username, SecureString password) { if (username == null) { throw new ArgumentNullException("username"); } if (password == null) { throw new ArgumentNullException("password"); } // SAML Token Request var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer", Lifetime = null, Delegatable = true, DelegatableSpecified = true }; // Security Token Request Authorization Header var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { User = username, Password = password } } }; // Request Authorization Server to Issue Bearer Token IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); // Extract the Raw XML Token from the Authorizations Server's Response return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }
/// <summary> /// Requests STS to validate given SAML Token /// </summary> /// <param name="token"></param> /// <returns></returns> public bool ValidateToken(XmlElement token) { var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Validate", TokenType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/Status", ValidateTarget = token }; var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel }; var response = securityContext.InvokeOperation(() => _stsServiceClient.ValidateAsync(securityTokenRequest).Result); // Check Saml Token Status is valid return(((StatusType)response.RequestSecurityTokenResponse.Items[0]).Code == "http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid"); }
/// <summary> /// Acquires Bearer Token by HoK Token. /// This is the use-case of server that holds HoK token to issue bearer token and /// use them to authorize requests to other services. /// </summary> /// <param name="hokToken"></param> /// <param name="signingCertitificate"></param> /// <returns></returns> public XmlElement IssueBearerTokenByHoKToken( XmlElement hokToken, X509Certificate2 signingCertitificate) { if (hokToken == null) { throw new ArgumentNullException("hokToken"); } // SAML Token Request var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer", Lifetime = null, Delegatable = true, DelegatableSpecified = true }; // Security Token Request Authorization Header var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { HolderOfKeyToken = hokToken }, SigningKey = signingCertitificate.PrivateKey } }; // Request Authorization Server to Issue HoK Token IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); // Extract the Raw XML Token from the Authorizations Server's Response return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }
/// <summary> /// Acquires Holder of Key Token by Certificate. /// HoK token issuance requires Clients to /// 1. Sign AcquireToken Request with the private key of their Signing Certificate /// 2. To present the public key of the Signing Certificate to the Authorization Server in the AcquireToken Request /// 3. Authorization Server validate the request signature is signed with the private key of the presented public key /// This way Authorization Server ensures request is not modified and the client has the private key corresponding the public key. /// HoK tokens are valid for longer period of time compared to the bearer tokens. /// HoK tokens can be used to acquire bearer tokens on behalf of the subject. This way servers /// can keep HoK and issue Bearer Tokens with which to present the Subject to other services. /// 4. HoK token can be delegatable to delegate authorization to other services to act on behalf of the subject. /// User authorizes one service to act on his behalf against another server /// </summary> /// <param name="signingCertitificate">Solution user certificate</param> /// <param name="lifetimeSpan"></param> /// <returns>Raw XML representation of the SAML 2.0 HoK Token</returns> public XmlElement IssueHoKTokenByCertificate( X509Certificate2 signingCertitificate, TimeSpan?lifetimeSpan = null) { // SAML Token Request var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey", Lifetime = GetLifetime(lifetimeSpan), DelegatableSpecified = true, Delegatable = true, SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" }; // Security Token Request Authorization Header var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { // Certificate which will be used by the Authorization Server to validate the signature of the request ClientCertificate = signingCertitificate }, // This Key will be used to sign the request SigningKey = signingCertitificate.PrivateKey } }; // Request Authorization Server to Issue HoK Token IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); // Extract the Raw XML Token from the Authorizations Server's Response return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }
public void AuthenticationAdd(string domain, string policyref) { RequestSecurityTokenType requestToken = new RequestSecurityTokenType(); requestToken.Id = "RST" + authId.ToString(); requestToken.RequestType = RequestTypeOpenEnum.httpschemasxmlsoaporgws200502trustIssue; requestToken.AppliesTo = new AppliesTo(); requestToken.AppliesTo.EndpointReference = new EndpointReferenceType(); requestToken.AppliesTo.EndpointReference.Address = new AttributedURIType(); requestToken.AppliesTo.EndpointReference.Address.Value = domain; if (policyref != null) { requestToken.PolicyReference = new PolicyReference(); requestToken.PolicyReference.URI = policyref; } auths.Add(requestToken); authId++; }
/// <summary> /// Renew token. This operation allows a long-lvide task operation to scheduled in a service /// giving the server a renewable token. Then the service can renew the token before use it /// to authorize access for the operation. /// Use-case: https://wiki.eng.vmware.com/SSO/UseCases#Scheduling_long_lived_task_.28delegation_.2B_renew.29 /// </summary> /// <param name="renewableToken"></param> /// <param name="signingCertificate"></param> /// <param name="lifetime"></param> /// <returns></returns> public XmlElement RenewToken( XmlElement renewableToken, X509Certificate2 signingCertificate, TimeSpan?lifetime = null) { if (renewableToken == null) { throw new ArgumentNullException("renewableToken"); } var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Renew", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", RenewTarget = renewableToken, Lifetime = GetLifetime(lifetime) }; var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { ClientCertificate = signingCertificate }, SigningKey = signingCertificate.PrivateKey } }; RenewResponse response = securityContext.InvokeOperation(() => _stsServiceClient.RenewAsync(securityTokenRequest).Result); return((XmlElement) response. RequestSecurityTokenResponse. Items[0]); #endregion }
/// <summary> /// /// </summary> /// <param name="hokToken"></param> /// <param name="signingCertificate"></param> /// <returns></returns> public XmlElement IssueHoKTokenByHoKToken( XmlElement hokToken, X509Certificate2 signingCertificate) { if (hokToken == null) { throw new ArgumentNullException("hokToken"); } var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey", SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", DelegatableSpecified = true, Delegatable = true }; var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { HolderOfKeyToken = hokToken }, SigningKey = signingCertificate.PrivateKey } }; IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }
public static SamlToken GetSamlBearerToken( string ssoUrl, string ssoUserName, string ssoPassword) { var binding = VimAuthenticationHelper.GetCustomBinding(); var address = new EndpointAddress(ssoUrl); var stsServiceClient = new STSService_PortTypeClient(binding, address); stsServiceClient.ClientCredentials.UserName.UserName = ssoUserName; stsServiceClient.ClientCredentials.UserName.Password = ssoPassword; RequestSecurityTokenType tokenType = new RequestSecurityTokenType(); /** * For this request we need at least the following element in the * RequestSecurityTokenType set * * 1. Lifetime - represented by LifetimeType which specifies the * lifetime for the token to be issued * * 2. Tokentype - "urnoasisnamestcSAML20assertion", which is the * class that models the requested token * * 3. RequestType - * "httpdocsoasisopenorgwssxwstrust200512Issue", as we want * to get a token issued * * 4. KeyType - * "httpdocsoasisopenorgwssxwstrust200512Bearer", * representing the kind of key the token will have. There are two * options namely bearer and holder-of-key * * 5. SignatureAlgorithm - * "httpwwww3org200104xmldsigmorersasha256", representing the * algorithm used for generating signature * * 6. Renewing - represented by the RenewingType which specifies * whether the token is renewable or not */ tokenType.TokenType = TokenTypeEnum.urnoasisnamestcSAML20assertion; tokenType.RequestType = RequestTypeEnum.httpdocsoasisopenorgwssxwstrust200512Issue; tokenType.KeyType = KeyTypeEnum.httpdocsoasisopenorgwssxwstrust200512Bearer; tokenType.SignatureAlgorithm = SignatureAlgorithmEnum.httpwwww3org200104xmldsigmorersasha256; tokenType.Delegatable = true; tokenType.DelegatableSpecified = true; LifetimeType lifetime = new LifetimeType(); AttributedDateTime created = new AttributedDateTime(); String createdDate = String.Format(dateFormat, DateTime.Now.ToUniversalTime()); created.Value = createdDate; lifetime.Created = created; AttributedDateTime expires = new AttributedDateTime(); TimeSpan duration = new TimeSpan(1, 10, 10); String expireDate = String.Format(dateFormat, DateTime.Now.Add(duration).ToUniversalTime()); expires.Value = expireDate; lifetime.Expires = expires; tokenType.Lifetime = lifetime; RenewingType renewing = new RenewingType(); renewing.Allow = false; renewing.OK = true; tokenType.Renewing = renewing; RequestSecurityTokenResponseCollectionType responseToken = stsServiceClient.Issue(tokenType); RequestSecurityTokenResponseType rstResponse = responseToken.RequestSecurityTokenResponse; XmlElement samlTokenXml = rstResponse.RequestedSecurityToken; SamlToken samlToken = new SamlToken(samlTokenXml); return(samlToken); }
private bool ProcessError(SecurityTokenService secureService, SoapException exception, MSNTicket msnticket, EventHandler onSuccess, EventHandler <ExceptionEventArgs> onError) { string errFedDirectLogin = @"Direct login to WLID is not allowed for this federated namespace"; if (exception == null) { return(false); } if (secureService.pp == null) { return(false); } uint errorCode = uint.Parse(secureService.pp.reqstatus.Remove(0, "0x".Length), NumberStyles.HexNumber); if (errorCode == 0x800488ee) { if (exception.Detail.InnerXml.IndexOf(errFedDirectLogin) != -1) { string fedLoginURL = string.Empty; string fedAuthURL = string.Empty; string fedBrandName = string.Empty; foreach (extPropertyType extProperty in secureService.pp.extProperties) { switch (extProperty.Name) { case "STSAuthURL": //STS means Security Token Service. fedLoginURL = extProperty.Value; break; case "AuthURL": fedAuthURL = extProperty.Value; break; case "AllowFedUsersWLIDSignIn": //Is it allow to login by MSN ? Not all feduser can log in with a WLM client. if (!bool.Parse(extProperty.Value)) { return(false); } break; case "FederationBrandName": fedBrandName = extProperty.Value; break; case "IsFederatedNS": if (!bool.Parse(extProperty.Value)) { return(false); } break; } } if (fedLoginURL == string.Empty) { return(false); } Uri fedLoginURI = new Uri(fedLoginURL); string strFedLoginURI = fedLoginURI.Scheme.ToUpperInvariant() + "://" + fedLoginURI.Host + (fedLoginURI.Scheme.ToLowerInvariant() == "https" ? ":443" : string.Empty) + "/" + fedLoginURI.PathAndQuery; SecurityTokenService fedSecureService = CreateSecurityTokenService(@"http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", strFedLoginURI); fedSecureService.Url = fedLoginURL; RequestSecurityTokenType token = new RequestSecurityTokenType(); token.Id = "RST0"; token.RequestType = RequestTypeOpenEnum.httpschemasxmlsoaporgws200502trustIssue; AppliesTo appliesTo = new AppliesTo(); appliesTo.EndpointReference = new EndpointReferenceType(); appliesTo.EndpointReference.Address = new AttributedURIType(); appliesTo.EndpointReference.Address.Value = strFedLoginURI.Remove(0, @"HTTPS://".Length); token.AppliesTo = appliesTo; RequestSecurityTokenResponseType response = null; if (onSuccess != null && onError != null) { //Async request. fedSecureService.RequestSecurityTokenCompleted += delegate(object sender, RequestSecurityTokenCompletedEventArgs e) { if (!e.Cancelled) { if (e.Error != null) { MSNPSharpException sexp = new MSNPSharpException(e.Error.Message + ". See innerexception for detail.", e.Error); onError(this, new ExceptionEventArgs(sexp)); return; } response = e.Result; if (response.RequestedSecurityToken == null || response.RequestedSecurityToken.Assertion == null) { return; } AssertionType assertion = response.RequestedSecurityToken.Assertion; secureService = CreateSecurityTokenService(@"http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", @"HTTPS://login.live.com:443//RST2.srf"); secureService.Security.Assertion = assertion; if (response.Lifetime != null) { secureService.Security.Timestamp.Created = response.Lifetime.Created; secureService.Security.Timestamp.Expires = response.Lifetime.Expires; } Authenticate(secureService, msnticket, onSuccess, onError); } }; fedSecureService.RequestSecurityTokenAsync(token, new object()); return(true); } else { //Sync request. try { response = fedSecureService.RequestSecurityToken(token); } catch (Exception ex) { MSNPSharpException sexp = new MSNPSharpException(ex.Message + ". See innerexception for detail.", ex); throw sexp; } if (response.RequestedSecurityToken == null) { return(false); } if (response.RequestedSecurityToken.Assertion == null) { return(false); } AssertionType assertion = response.RequestedSecurityToken.Assertion; secureService = CreateSecurityTokenService(@"http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", @"HTTPS://login.live.com:443//RST2.srf"); secureService.Security.Assertion = assertion; Authenticate(secureService, msnticket, onSuccess, onError); return(true); } } } return(false); }
/// <summary> /// Acquires delegate to HoK token by another solution HoK token. /// This method issues Token delegated to /// service with id <param name="delegateToServiceId"></param> which is registered in the /// SSO with solution user <param name="delegateToSolutionUser"></param> /// https://wiki.eng.vmware.com/SSO/UseCases#Executing_tasks_on_behalf_of_an_user_.28delegation.29 /// </summary> /// <param name="hokToken"></param> /// <param name="signingCertitificate"></param> /// <param name="delegateToServiceId"></param> /// <param name="delegateToSolutionUser"></param> /// <param name="renewableOk">True to allow token to be renewed after it has expired. Default is false, it is recommended to remain with default value.</param> /// <returns>Raw XML representation of the SAML 2.0 DelegateTo token</returns> public XmlElement IssueDelegateToHoKTokenBySolutionHoK( XmlElement hokToken, X509Certificate2 signingCertificate, string delegateToServiceId, string delegateToSolutionUser, TimeSpan?lifetime = null, bool?renewable = null, bool renewableOk = false) { // SAML Token Request var securityTokenRequest = new RequestSecurityTokenType { RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue", TokenType = "urn:oasis:names:tc:SAML:2.0:assertion", KeyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey", Lifetime = GetLifetime(lifetime), DelegateTo = new DelegateToType { UsernameToken = new UsernameTokenType { Id = $"Id-{Guid.NewGuid().ToString()}", Username = new AttributedString { Id = $"Id-{delegateToServiceId}", Value = delegateToSolutionUser } }, }, DelegatableSpecified = true, Delegatable = true, SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" }; if (renewable != null) { securityTokenRequest.Renewing = new RenewingType { Allow = renewable.Value, AllowSpecified = true, OK = renewableOk, OKSpecified = true, }; } // Security Token Request Authorization Header var securityContext = new WsSecurityContext { ClientChannel = _stsServiceClient.InnerChannel, Properties = { Credentials = { HolderOfKeyToken = hokToken }, SigningKey = signingCertificate.PrivateKey } }; // Request Authorization Server to Issue HoK Token IssueResponse response = securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result); // Extract the Raw XML Token from the Authorizations Server's Response return((XmlElement) response. RequestSecurityTokenResponseCollection. RequestSecurityTokenResponse. Items[0]); }