internal static void RenewIfExpired(NSMessageHandler nsMessageHandler, SSOTicketType renew) { CheckCleanup(); if (nsMessageHandler == null || nsMessageHandler.Credentials == null) { return; } string authUser = nsMessageHandler.Credentials.Account; string authPassword = nsMessageHandler.Credentials.Password; if (String.IsNullOrEmpty(authUser) || String.IsNullOrEmpty(authPassword)) { return; } string sha256key = MSNTicket.ComputeSHA(authUser, authPassword); MSNTicket ticket = GetFromCacheOrCreateNewWithLock(sha256key, nsMessageHandler.Credentials); ExpiryState es = ticket.Expired(renew); if (es == ExpiryState.NotExpired) { nsMessageHandler.MSNTicket = ticket; } else if (es == ExpiryState.Expired || es == ExpiryState.WillExpireSoon) { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Re-new ticket: " + renew, "SingleSignOnManager"); SingleSignOn sso = new SingleSignOn(nsMessageHandler, ticket.Policy); sso.AddAuths(renew); if (es == ExpiryState.WillExpireSoon) { nsMessageHandler.MSNTicket = ticket; // The ticket is in cache but it will expire soon. // Do ASYNC call. sso.Authenticate(ticket, delegate(object sender, EventArgs e) { AddToCacheWithLock(ticket); }, delegate(object sender, ExceptionEventArgs e) { DeleteFromCacheWithLock(sha256key); } ); } else { // The ticket expired but we need this ticket absolutely. // Do SYNC call. AuthenticateRetryAndUpdateCacheSync(sso, ticket, sha256key, 3); nsMessageHandler.MSNTicket = ticket; } } }
private static void AddToCacheWithLock(MSNTicket ticket) { try { lock (SyncObject) { if (ticket.SSOTickets.Count > 0 && false == String.IsNullOrEmpty(ticket.Sha256Key)) { authenticatedTicketsCache[ticket.Sha256Key] = ticket; ticket.DeleteTick = MSNTicket.NextDeleteTick(); } } } catch (Exception error) { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Add to cache error: " + error.StackTrace, "SingleSignOnManager"); } }
private static MSNTicket GetFromCacheOrCreateNewWithLock(string sha256key, Credentials creds) { MSNTicket ticket = null; lock (SyncObject) { if (authenticatedTicketsCache.ContainsKey(sha256key)) { // Hit delete tick ticket = authenticatedTicketsCache[sha256key]; ticket.DeleteTick = MSNTicket.NextDeleteTick(); } else { ticket = new MSNTicket(creds); } } return(ticket); }
private static void AuthenticateRetryAndUpdateCacheSync(SingleSignOn sso, MSNTicket ticket, string sha256key, int retryCount) { // NO TICKET. WE NEED SYNC CALL! // DILEMMA: // 1 - We need this ticket (absolutely) // 2 - What we do if connection error occured! // ANSWER: Try 3 times if it is soft error. int retries = retryCount; do { try { sso.Authenticate(ticket); AddToCacheWithLock(ticket); break; } catch (AuthenticationException authExc) { DeleteFromCacheWithLock(sha256key); throw authExc; } catch (MSNPSharpException msnpExc) { if (msnpExc.InnerException == null) { DeleteFromCacheWithLock(sha256key); throw msnpExc; } WebException webExc = msnpExc.InnerException as WebException; if (webExc == null) { DeleteFromCacheWithLock(sha256key); throw msnpExc.InnerException; } // Handle soft errors switch (webExc.Status) { case WebExceptionStatus.ConnectionClosed: case WebExceptionStatus.KeepAliveFailure: case WebExceptionStatus.ReceiveFailure: case WebExceptionStatus.SendFailure: case WebExceptionStatus.Timeout: case WebExceptionStatus.UnknownError: { // Don't delete the ticket from cache retries--; break; } default: { DeleteFromCacheWithLock(sha256key); throw msnpExc.InnerException; } } } }while (retries > 0); }
internal static void Authenticate( NSMessageHandler nsMessageHandler, string policy, EventHandler onSuccess, EventHandler <ExceptionEventArgs> onError) { CheckCleanup(); if (nsMessageHandler == null || nsMessageHandler.Credentials == null) { return; } string authUser = nsMessageHandler.Credentials.Account; string authPassword = nsMessageHandler.Credentials.Password; if (String.IsNullOrEmpty(authUser) || String.IsNullOrEmpty(authPassword)) { return; } string sha256key = MSNTicket.ComputeSHA(authUser, authPassword); MSNTicket ticket = GetFromCacheOrCreateNewWithLock(sha256key, nsMessageHandler.Credentials); SSOTicketType[] ssos = (SSOTicketType[])Enum.GetValues(typeof(SSOTicketType)); SSOTicketType expiredtickets = SSOTicketType.None; foreach (SSOTicketType ssot in ssos) { if (ExpiryState.NotExpired != ticket.Expired(ssot)) { expiredtickets |= ssot; } } if (expiredtickets == SSOTicketType.None) { nsMessageHandler.MSNTicket = ticket; if (onSuccess != null) { onSuccess(nsMessageHandler, EventArgs.Empty); } } else { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Request new tickets: " + expiredtickets, "SingleSignOnManager"); SingleSignOn sso = new SingleSignOn(nsMessageHandler, policy); sso.AddAuths(expiredtickets); // ASYNC if (onSuccess != null && onError != null) { try { sso.Authenticate(ticket, delegate(object sender, EventArgs e) { try { AddToCacheWithLock(ticket); // Check Credentials again. Owner may sign off while SSOing. if (nsMessageHandler.Credentials != null && nsMessageHandler.Credentials.Account == authUser && nsMessageHandler.Credentials.Password == authPassword && nsMessageHandler.IsSignedIn == false) { NSMessageProcessor nsmp = nsMessageHandler.MessageProcessor as NSMessageProcessor; if (nsmp != null && nsmp.Connected) { nsMessageHandler.MSNTicket = ticket; onSuccess(nsMessageHandler, e); } } } catch (Exception ex) { DeleteFromCacheWithLock(sha256key); onError(nsMessageHandler, new ExceptionEventArgs(ex)); } }, delegate(object sender, ExceptionEventArgs e) { DeleteFromCacheWithLock(sha256key); onError(nsMessageHandler, e); }); } catch (Exception error) { DeleteFromCacheWithLock(sha256key); onError(nsMessageHandler, new ExceptionEventArgs(error)); } } else { // SYNC AuthenticateRetryAndUpdateCacheSync(sso, ticket, sha256key, 3); nsMessageHandler.MSNTicket = ticket; } } }
private static void AuthenticateRetryAndUpdateCacheSync(SingleSignOn sso, MSNTicket ticket, string sha256key, int retryCount) { // NO TICKET. WE NEED SYNC CALL! // DILEMMA: // 1 - We need this ticket (absolutely) // 2 - What we do if connection error occured! // ANSWER: Try 3 times if it is soft error. int retries = retryCount; do { try { sso.Authenticate(ticket); AddToCacheWithLock(ticket); break; } catch (AuthenticationException authExc) { DeleteFromCacheWithLock(sha256key); throw authExc; } catch (MSNPSharpException msnpExc) { if (msnpExc.InnerException == null) { DeleteFromCacheWithLock(sha256key); throw msnpExc; } WebException webExc = msnpExc.InnerException as WebException; if (webExc == null) { DeleteFromCacheWithLock(sha256key); throw msnpExc.InnerException; } // Handle soft errors switch (webExc.Status) { case WebExceptionStatus.ConnectionClosed: case WebExceptionStatus.KeepAliveFailure: case WebExceptionStatus.ReceiveFailure: case WebExceptionStatus.SendFailure: case WebExceptionStatus.Timeout: case WebExceptionStatus.UnknownError: { // Don't delete the ticket from cache retries--; break; } default: { DeleteFromCacheWithLock(sha256key); throw msnpExc.InnerException; } } } } while (retries > 0); }
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; }
private void Authenticate(SecurityTokenService securService, MSNTicket msnticket, EventHandler onSuccess, EventHandler <ExceptionEventArgs> onError) { if (user.Split('@').Length > 1) { if (user.Split('@')[1].ToLower(CultureInfo.InvariantCulture) == "msn.com") { securService.Url = @"https://msnia.login.live.com/RST2.srf"; } } else { AuthenticationException authenticationException = new AuthenticationException("Invalid account. The account must contain @ char"); if (onError != null && onSuccess != null) { onError(this, new ExceptionEventArgs(authenticationException)); } else { throw authenticationException; } } RequestMultipleSecurityTokensType mulToken = new RequestMultipleSecurityTokensType(); mulToken.Id = "RSTS"; mulToken.RequestSecurityToken = auths.ToArray(); // ASYNC if (onSuccess != null && onError != null) { securService.RequestMultipleSecurityTokensCompleted += delegate(object sender, RequestMultipleSecurityTokensCompletedEventArgs e) { if (!e.Cancelled) { if (e.Error != null) { SoapException sex = e.Error as SoapException; if (sex != null && ProcessError(securService, sex, msnticket, onSuccess, onError)) { return; } MSNPSharpException sexp = new MSNPSharpException(e.Error.Message + ". See innerexception for detail.", e.Error); if (securService.pp != null) { sexp.Data["Code"] = securService.pp.reqstatus; //Error code } onError(this, new ExceptionEventArgs(sexp)); } else if (e.Result != null) { GetTickets(e.Result, securService, msnticket); onSuccess(this, EventArgs.Empty); } else { // Is this possible? Answer: No. } } }; securService.RequestMultipleSecurityTokensAsync(mulToken, new object()); } else { try { RequestSecurityTokenResponseType[] result = securService.RequestMultipleSecurityTokens(mulToken); if (result != null) { GetTickets(result, securService, msnticket); } } catch (SoapException sex) { if (ProcessError(securService, sex, msnticket, onSuccess, onError)) { return; } throw sex; } catch (Exception ex) { MSNPSharpException sexp = new MSNPSharpException(ex.Message + ". See innerexception for detail.", ex); if (securService.pp != null) { sexp.Data["Code"] = securService.pp.reqstatus; //Error code } throw sexp; } } }
private void Authenticate(SecurityTokenService securService, MSNTicket msnticket, EventHandler onSuccess, EventHandler<ExceptionEventArgs> onError) { if (user.Split('@').Length > 1) { if (user.Split('@')[1].ToLower(CultureInfo.InvariantCulture) == "msn.com") { securService.Url = @"https://msnia.login.live.com/RST2.srf"; } } else { AuthenticationException authenticationException = new AuthenticationException("Invalid account. The account must contain @ char"); if (onError != null && onSuccess != null) onError(this, new ExceptionEventArgs(authenticationException)); else throw authenticationException; } RequestMultipleSecurityTokensType mulToken = new RequestMultipleSecurityTokensType(); mulToken.Id = "RSTS"; mulToken.RequestSecurityToken = auths.ToArray(); // ASYNC if (onSuccess != null && onError != null) { securService.RequestMultipleSecurityTokensCompleted += delegate(object sender, RequestMultipleSecurityTokensCompletedEventArgs e) { if (!e.Cancelled) { if (e.Error != null) { SoapException sex = e.Error as SoapException; if (sex != null && ProcessError(securService, sex, msnticket, onSuccess, onError)) return; MSNPSharpException sexp = new MSNPSharpException(e.Error.Message + ". See innerexception for detail.", e.Error); if (securService.pp != null) sexp.Data["Code"] = securService.pp.reqstatus; //Error code onError(this, new ExceptionEventArgs(sexp)); } else if (e.Result != null) { GetTickets(e.Result, securService, msnticket); onSuccess(this, EventArgs.Empty); } else { // Is this possible? Answer: No. } } }; securService.RequestMultipleSecurityTokensAsync(mulToken, new object()); } else { try { RequestSecurityTokenResponseType[] result = securService.RequestMultipleSecurityTokens(mulToken); if (result != null) { GetTickets(result, securService, msnticket); } } catch (SoapException sex) { if (ProcessError(securService, sex, msnticket, onSuccess, onError)) return; throw sex; } catch (Exception ex) { MSNPSharpException sexp = new MSNPSharpException(ex.Message + ". See innerexception for detail.", ex); if (securService.pp != null) sexp.Data["Code"] = securService.pp.reqstatus; //Error code throw sexp; } } }
private void GetTickets(RequestSecurityTokenResponseType[] result, SecurityTokenService securService, MSNTicket msnticket) { if (securService.pp != null) { if (securService.pp.credProperties != null) { foreach (credPropertyType credproperty in securService.pp.credProperties) { if (credproperty.Name == "MainBrandID") { msnticket.MainBrandID = credproperty.Value; } if (credproperty.Name == "CID" && !String.IsNullOrEmpty(credproperty.Value)) { msnticket.OwnerCID = long.Parse(credproperty.Value, NumberStyles.HexNumber); } } } if (securService.pp.extProperties != null) { foreach (extPropertyType extproperty in securService.pp.extProperties) { if (extproperty.Name == "CID" && !String.IsNullOrEmpty(extproperty.Value)) { msnticket.OwnerCID = long.Parse(extproperty.Value, NumberStyles.HexNumber); } } } } foreach (RequestSecurityTokenResponseType token in result) { SSOTicketType ticketype = SSOTicketType.None; switch (token.AppliesTo.EndpointReference.Address.Value) { case "contacts.msn.com": ticketype = SSOTicketType.Contact; break; case "messengerclear.live.com": ticketype = SSOTicketType.Clear; break; case "storage.msn.com": ticketype = SSOTicketType.Storage; break; case "sup.live.com": ticketype = SSOTicketType.WhatsUp; break; case "directory.services.live.com": ticketype = SSOTicketType.Directory; break; case "rpstauth.live.com": ticketype = SSOTicketType.RPST; break; } SSOTicket ssoticket = new SSOTicket(ticketype); if (token.AppliesTo != null) ssoticket.Domain = token.AppliesTo.EndpointReference.Address.Value; if (token.RequestedSecurityToken.BinarySecurityToken != null) ssoticket.Ticket = token.RequestedSecurityToken.BinarySecurityToken.Value; if (token.RequestedProofToken != null && token.RequestedProofToken.BinarySecret != null) { ssoticket.BinarySecret = token.RequestedProofToken.BinarySecret.Value; } if (token.Lifetime != null) { ssoticket.Created = XmlConvert.ToDateTime(token.Lifetime.Created.Value, "yyyy-MM-ddTHH:mm:ssZ"); ssoticket.Expires = XmlConvert.ToDateTime(token.Lifetime.Expires.Value, "yyyy-MM-ddTHH:mm:ssZ"); } lock (msnticket.SSOTickets) { msnticket.SSOTickets[ticketype] = ssoticket; } } }
/// <summary> /// Authenticate the specified user. By asynchronous or synchronous ways. /// </summary> /// <param name='msnticket'> /// Msnticket. /// </param> /// <param name='onSuccess'> /// Callback when the authentication was passed. /// </param> /// <param name='onError'> /// Callback when the authentication encounts errors. /// </param> /// <exception cref='AuthenticationException'> /// Is thrown when the authentication failed and the request is a synchronous request. /// Or the <paramref name="onError"/> callback will be called. /// </exception> /// <remarks> /// The method is asynchronous only when both <paramref name="onSuccess"/> and <paramref name="onError"/> are not null. /// Otherwise it will perform a synchronous request. /// </remarks> public void Authenticate(MSNTicket msnticket, EventHandler onSuccess, EventHandler<ExceptionEventArgs> onError) { SecurityTokenService securService = CreateSecurityTokenService(@"http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", @"HTTPS://login.live.com:443//RST2.srf"); Authenticate(securService, msnticket, onSuccess, onError); }
public void Authenticate(MSNTicket msnticket) { Authenticate(msnticket, null, null); }
private static MSNTicket GetFromCacheOrCreateNewWithLock(string sha256key, Credentials creds) { MSNTicket ticket = null; lock (SyncObject) { if (authenticatedTicketsCache.ContainsKey(sha256key)) { // Hit delete tick ticket = authenticatedTicketsCache[sha256key]; ticket.DeleteTick = MSNTicket.NextDeleteTick(); } else { ticket = new MSNTicket(creds); } } return ticket; }
/// <summary> /// Clears all resources associated with a nameserver session. /// </summary> /// <remarks> /// Called after we the processor has disconnected. This will clear the contactlist and free other resources. /// </remarks> protected virtual bool Clear() { // 0. Remove pong if (pong != null) { pong.Elapsed -= pong_Elapsed; try { if (pong.Enabled) pong.Enabled = false; pong.Dispose(); } catch (ObjectDisposedException) { } finally { pong = null; } } // 1. Cancel transfers p2pHandler.Dispose(); // 2. Cancel web services. MSNTicket must be here. msnTicket = MSNTicket.Empty; ContactService.Clear(); StorageService.Clear(); WhatsUpService.Clear(); DirectoryService.Clear(); // 3. isSignedIn must be here... // a) ContactService.Clear() merges and saves addressbook if isSignedIn=true. // b) Owner.ClientCapabilities = ClientCapabilities.None doesn't send CHG command if isSignedIn=false. bool signInStatus = IsSignedIn; isSignedIn = false; externalEndPoint = null; adlState.Reset(); // 4. Clear contact lists and circle list. ContactList.Reset(); CircleList.Clear(); ContactGroups.Clear(); //5. Reset contact manager. ContactManager.Reset(); //6. Reset censor words CensorWords.Clear(); //7. Clear multiparties lock (multiParties) multiParties.Clear(); return signInStatus; }
/// <summary> /// Authenticate the specified user. By asynchronous or synchronous ways. /// </summary> /// <param name='msnticket'> /// Msnticket. /// </param> /// <param name='onSuccess'> /// Callback when the authentication was passed. /// </param> /// <param name='onError'> /// Callback when the authentication encounts errors. /// </param> /// <exception cref='AuthenticationException'> /// Is thrown when the authentication failed and the request is a synchronous request. /// Or the <paramref name="onError"/> callback will be called. /// </exception> /// <remarks> /// The method is asynchronous only when both <paramref name="onSuccess"/> and <paramref name="onError"/> are not null. /// Otherwise it will perform a synchronous request. /// </remarks> public void Authenticate(MSNTicket msnticket, EventHandler onSuccess, EventHandler <ExceptionEventArgs> onError) { SecurityTokenService securService = CreateSecurityTokenService(@"http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", @"HTTPS://login.live.com:443//RST2.srf"); Authenticate(securService, msnticket, onSuccess, onError); }
private void GetTickets(RequestSecurityTokenResponseType[] result, SecurityTokenService securService, MSNTicket msnticket) { if (securService.pp != null) { if (securService.pp.credProperties != null) { foreach (credPropertyType credproperty in securService.pp.credProperties) { if (credproperty.Name == "MainBrandID") { msnticket.MainBrandID = credproperty.Value; } if (credproperty.Name == "CID" && !String.IsNullOrEmpty(credproperty.Value)) { msnticket.OwnerCID = long.Parse(credproperty.Value, NumberStyles.HexNumber); } } } if (securService.pp.extProperties != null) { foreach (extPropertyType extproperty in securService.pp.extProperties) { if (extproperty.Name == "CID" && !String.IsNullOrEmpty(extproperty.Value)) { msnticket.OwnerCID = long.Parse(extproperty.Value, NumberStyles.HexNumber); } } } } foreach (RequestSecurityTokenResponseType token in result) { SSOTicketType ticketype = SSOTicketType.None; switch (token.AppliesTo.EndpointReference.Address.Value) { case "contacts.msn.com": ticketype = SSOTicketType.Contact; break; case "messengerclear.live.com": ticketype = SSOTicketType.Clear; break; case "storage.msn.com": ticketype = SSOTicketType.Storage; break; case "sup.live.com": ticketype = SSOTicketType.WhatsUp; break; case "directory.services.live.com": ticketype = SSOTicketType.Directory; break; case "rpstauth.live.com": ticketype = SSOTicketType.RPST; break; } SSOTicket ssoticket = new SSOTicket(ticketype); if (token.AppliesTo != null) { ssoticket.Domain = token.AppliesTo.EndpointReference.Address.Value; } if (token.RequestedSecurityToken.BinarySecurityToken != null) { ssoticket.Ticket = token.RequestedSecurityToken.BinarySecurityToken.Value; } if (token.RequestedProofToken != null && token.RequestedProofToken.BinarySecret != null) { ssoticket.BinarySecret = token.RequestedProofToken.BinarySecret.Value; } if (token.Lifetime != null) { ssoticket.Created = XmlConvert.ToDateTime(token.Lifetime.Created.Value, "yyyy-MM-ddTHH:mm:ssZ"); ssoticket.Expires = XmlConvert.ToDateTime(token.Lifetime.Expires.Value, "yyyy-MM-ddTHH:mm:ssZ"); } lock (msnticket.SSOTickets) { msnticket.SSOTickets[ticketype] = ssoticket; } } }
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); }