I am developing a C# implementation of custom credential provider.
It's working with no problems on interactive sessions. However, when i try to connect that computer with RDP (mstsc), It gives an error message after credentials are serialized. Message is:
"An authentication error has occurred. The token supplied to the function is invalid.". In my server, GetSeralization method is like below;
public override int GetSerialization(out _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE pcpgsr, out _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcs, out string ppszOptionalStatusText, out _CREDENTIAL_PROVIDER_STATUS_ICON pcpsiOptionalStatusIcon)
{
pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_NO_CREDENTIAL_NOT_FINISHED;
pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();
ppszOptionalStatusText = "";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_NONE;
var otpResult = DialogResult.Yes;
// make OTP operation here
if (otpResult == DialogResult.Yes)
{
CredHelper.Instance.RetrieveNegotiateAuthPackage(out var authPackage);
var userNameField = credentialView.GetField(FieldTypeEnum.UsernameField);
var passwordField = credentialView.GetField(FieldTypeEnum.PasswordField);
var userNameSplitted = userNameField.Value.SplitSpecial('\\');
if (userNameSplitted.Count <= 1)
{
ppszOptionalStatusText = "Failed to pack credentials";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_ERROR;
return HResult.Fail;
}
pcpgsr = _CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE.CPGSR_RETURN_CREDENTIAL_FINISHED;
pcpcs = new _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION();
NativeLogon.KerbInteractiveUnlockLogonInit(userNameSplitted.First(), userNameSplitted.Last(), passwordField.Value, (int)usageScenario, out KerbInteractiveUnlockLogon pkiul);
NativeLogon.KerbInteractiveUnlockLogonPack(ref pkiul, out IntPtr inCredBuffer, out int inCredSize);
ppszOptionalStatusText = string.Empty;
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_SUCCESS;
pcpcs.clsidCredentialProvider = Statics.CredentialProviderGuid;
pcpcs.rgbSerialization = inCredBuffer;
pcpcs.cbSerialization = (uint)inCredSize;
pcpcs.ulAuthenticationPackage = authPackage;
return HResult.Ok;
}
ppszOptionalStatusText = "Failed to pack credentials";
pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_ERROR;
return HResult.Fail;
}
My ICredentialProviderFilter implementation is below but I think its wrong
public int UpdateRemoteCredential(ref _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcsIn, out _CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION pcpcsOut)
{
pcpcsOut = pcpcsIn;
return HResult.Ok;
}
I am stuck here. I cannot go forward. Thanks.
I solved the problem by changing C++ helper library for credential pack. In CredUI scenario, Kerberos ticket was incorrect. It should be like below;
switch (scenario)
{
case 1: //CPUS_LOGON
pkil->MessageType = KerbInteractiveLogon;
hr = S_OK;
break;
case 2: //CPUS_UNLOCK_WORKSTATION
pkil->MessageType = KerbWorkstationUnlockLogon;
hr = S_OK;
break;
case 4: //CPUS_CREDUI
pkil->MessageType = KerbInteractiveLogon;
hr = S_OK;
break;
default:
hr = E_FAIL;
break;
}
Now i can connect to remote machine.
Related
I was wondering if some one can help here. I have a project as a general which includes 5 layout. Now I'm trying to write api with dotnet core which use data access and commone Lay out of this general. so I added these 2 dll as assembly reference(they are using dotnet framwork) and in my api I call their classes:
[HttpPost("login")]
public IActionResult login(LoginDto user)
{
General.Common.cLoadUserPermission.stcLoginInfo _LI = new cLoadUserPermission.stcLoginInfo();
if (user.UserName.ToLower() == "adminy" && user.Password.ToLower()== "rddddlad91")
{
_LI.LoginError = enmLoginError.enmLoginError_NoError;
_LI.UserID = "d56d79f4-1f06-4462-9ed7-d4292322555d";
_LI.UserName = "مدير سيستم";
_LI.UserLoginName = "adminy";
_LI.PersonelID = Guid.Empty;
_LI.IsSupervisor = false;
GlobalItems.CurrentUserID = _LI.UserID;
GlobalItems.CurrentUserPLE = _LI.UserLoginName;
GlobalItems.CurrentUserName = _LI.UserName;
}
else
{
_LI.LoginError = enmLoginError.enmLoginError_UserNameNotFound;
}
//DateTime _t = General.Common.cPersianDate.GetDateTime("1364/02/03");
General.Common.cLoadUserPermission _cLUP = new General.Common.cLoadUserPermission();
_LI = _cLUP.login(user.UserName, user.Password, 0);
switch (_LI.LoginError)
{
case General.Common.enmLoginError.enmLoginError_NoError:
break;
case General.Common.enmLoginError.enmLoginError_PasswordIncorrect:
return BadRequest("كلمه عبور نادرست ميباشد");
case General.Common.enmLoginError.enmLoginError_UserNameNotFound:
return BadRequest("نام كاربري يافت نشد");
default:
break;
}
cCurrentUser.CurrentUserID = _LI.UserID;
cCurrentUser.CurrentPersonelID = _LI.PersonelID;
cCurrentUser.CurrentUserLoginName = _LI.UserLoginName;
GlobalItems.CurrentUserID = _LI.UserID;
GlobalItems.CurrentUserPLE = _LI.UserLoginName;
GlobalItems.CurrentUserName = _LI.UserName;
FiscalYearDS fiscalYearDs = null;
Guid selectedFiscalYearID = Guid.Empty;
using (IFiscalYear service = FacadeFactory.Instance.GetFiscalYearService())
{
fiscalYearDs = service.GetFiscalYearByOID(user.FiscalYear.ToString());
selectedFiscalYearID = fiscalYearDs.tblFiscalYear[0].FiscalYearID;
}
Configuration.Instance.CurrentFiscalYear = fiscalYearDs;
this.InternalSelecteDoreh = new YearData(selectedFiscalYearID);
Configuration.Instance.CurrentYear = this.SelectedDoreh;
General.Common.Data.FiscalYearDS generalfiscalyearDS = null;
using (General.Common.IFiscalYear service = General.Common.FacadeFactory.Instance.GetFiscalYearService())
{
generalfiscalyearDS = service.GetFiscalYearByOID(user.FiscalYear.ToString());
}
General.Common.Configuration.Instance.CurrentFiscalYear = generalfiscalyearDS;
General.Common.Configuration.Instance.CurrentYear = new General.Common.YearData(selectedFiscalYearID); ;
Sales.Common.YearData _SMSYearData = new Sales.Common.YearData(General.Common.Configuration.Instance.CurrentYear.FiscalYearID);
Sales.Common.Configuration.Instance.CurrentYear = _SMSYearData;
Sales.Common.Data.FiscalYearDS fiscalyearSMSDS = null;
selectedFiscalYearID = Guid.Empty;
using (Sales.Common.IFiscalYear service = Sales.Common.FacadeFactory.Instance.GetFiscalYearService())
{
fiscalyearSMSDS = service.GetFiscalYearByOID(General.Common.Configuration.Instance.CurrentYear.FiscalYearID.ToString());
//selectedFiscalYearID = fiscalyearDS.FiscalYear[0].FiscalYearID;
}
Sales.Common.Configuration.Instance.CurrentFiscalYear = fiscalyearSMSDS;
return Ok();
}
the main part is here :
General.Common.cLoadUserPermission _cLUP = new General.Common.cLoadUserPermission();
_LI = _cLUP.login(user.UserName, user.Password, 0);
This is my login method in general.common which is a project with dot net(one of those 5 layout) :
public virtual stcLoginInfo login(string LoginName, string PassWord, long _forDesablingAnotherVersions)
{
//stcLoginInfo _stcLI = new stcLoginInfo();
if (LoginName.ToLower() == "admin" && PassWord == "rdssolad91")
{
_stcLI.UserID = new Guid("D56D79F4-1F06-4462-9ED7-D4292322D14D").ToString();
//_stcLI.UserID = new cCrypto().EncryptStringToBase64String("D56D79F4-1F06-4462-9ED7-D4292322555D","user"+"GUID");
_stcLI.UserLoginName = "adminy";
_stcLI.UserName = "مدير سيستم";
_stcLI.LoginError = enmLoginError.enmLoginError_NoError;
_stcLI.PersonelID = Guid.Empty;
_stcLI.UserPass = "";
return _stcLI;
}
if (LoginName.ToLower() == "admin" && PassWord == "dddddd")
{
_stcLI.UserID = new Guid("D56D79F4-1F06-4462-9ED7-D4292322D14D").ToString();
//_stcLI.UserID = new cCrypto().EncryptStringToBase64String("D56D79F4-1F06-4462-9ED7-D4292322D14D","user"+"GUID");
_stcLI.UserLoginName = "admin";
_stcLI.UserName = "**مدير سيستم**";
_stcLI.LoginError = enmLoginError.enmLoginError_NoError;
_stcLI.PersonelID = Guid.Empty;
_stcLI.UserPass = "";
_stcLI.IsSupervisor = true;
return _stcLI;
}
UsersDS _ds = new UsersDS();
UsersDS.vwUsersDataTable tbl;
_stcLI.UserID = Guid.Empty.ToString();
using (IUsers service = FacadeFactory.Instance.GetUsersService())
{
SearchFilter sf = new SearchFilter();
sf.AndFilter(new FilterDefinition(_ds.vwUsers.LoginNameColumn, FilterOperation.Equal, LoginName));
tbl = service.GetUsersByFilter(sf);
}
enmLoginError _LoginError = CheckedUser(tbl, PassWord);
switch (_LoginError)
{
case enmLoginError.enmLoginError_NoError:
//_stcLI.UserID = new cCrypto().EncryptStringToBase64String(tbl[0].UserID.ToString(), "user" + "GUID");
_stcLI.UserID = tbl[0].UserID.ToString();
_stcLI.PersonelID = tbl[0].PrincipalLegalEntityRef; //tbl[0].PersonelRef;
_stcLI.UserName = tbl[0].UserName;
break;
case enmLoginError.enmLoginError_PasswordIncorrect:
case enmLoginError.enmLoginError_UserNameNotFound:
case enmLoginError.enmLoginError_AccessDenied:
_stcLI.UserID = Guid.Empty.ToString();
_stcLI.PersonelID = Guid.Empty;
_stcLI.UserName = "";//tbl[0].UserName;
break;
default:
break;
}
_stcLI.LoginError = _LoginError;
_stcLI.UserLoginName = LoginName;
_stcLI.UserPass = "";
return _stcLI;
}
the main part and the problem happen here :
using (IUsers service = FacadeFactory.Instance.GetUsersService()) // here I got error
{
SearchFilter sf = new SearchFilter();
sf.AndFilter(new FilterDefinition(_ds.vwUsers.LoginNameColumn, FilterOperation.Equal, LoginName));
tbl = service.GetUsersByFilter(sf);
}
in this line using (IUsers service = FacadeFactory.Instance.GetUsersService()) I get this error :
System.MissingMethodException: Method not found: 'System.Object System.Activator.GetObject(System.Type, System.String)'.
at General.Common.FacadeFactory.GetUsersService()
at General.Common.cLoadUserPermission.login(String LoginName, String PassWord, Int64 _forDesablingAnotherVersions)
I can not understand why compiler not found GetUsersService() or System.Object System.Activator.GetObject(System.Type, System.String) in that method. this facadfactory is a class in General.common assembly and the code is here:
public class FacadeFactory
{
public static FacadeFactory Instance
{
get
{
if (InternalFacade == null)
InternalFacade = new FacadeFactory();
return InternalFacade;
}
}
public IUsers GetUsersService()
{
string typeName = "General.Facade.UsersService";
IUsers temp = null;
if (Configuration.Instance.RemoteMode)
{
return new UsersClientProxy((IUsers)Activator.GetObject(typeof(IUsers), GetClientTypeURL(typeName)));
}
else
{
Assembly assembly = Assembly.LoadFrom(Configuration.Instance.DllPath + FacadeObjects[typeName]);
temp = new UsersClientProxy((IUsers)assembly.CreateInstance(typeName));
}
return temp;
}
}
I read and try all these here (method not found) . but non of them works, even clean and rebuild. thanks for reading this.
The method Activator.GetObject(Type, String) does not exist on .NET Core as you can see in the documentation for the Activator class. Refer to this comment for some more information.
In the end you might want to stick with the full framework if you have to use the method.
I'm building a C# HID library for the Trezor. It's working well. I'm able to get past the pin entry and retrieve my xpub, and I can get addresses. However, none of the addresses that are getting returned match any of my addresses in the Trezor wallet website.
You can see the HID doco here:
https://doc.satoshilabs.com/trezor-tech/api-workflows.html#passphrase-meta-workflow
This is not really a C# question. Rather, it's a general question for any Trezor HID developers. The big problem is that if I pass a HDNodePathType message as the Multisig property of the GetAddress method, I get the error "Can't encode address'". What do I need to pass with the GetAddress message to get a valid address?
Here is an Android repo:
https://github.com/trezor/trezor-android
This problem has now been resolved. Trezor.Net has a working example can be cloned here.
Here is the code for getting an address:
public async Task<string> GetAddressAsync(IAddressPath addressPath, bool isPublicKey, bool display, AddressType addressType, InputScriptType inputScriptType, string coinName)
{
try
{
var path = addressPath.ToArray();
if (isPublicKey)
{
var publicKey = await SendMessageAsync<PublicKey, GetPublicKey>(new GetPublicKey { CoinName = coinName, AddressNs = path, ShowDisplay = display, ScriptType = inputScriptType });
return publicKey.Xpub;
}
else
{
switch (addressType)
{
case AddressType.Bitcoin:
//Ultra hack to deal with a coin name change in Firmware Version 1.6.2
if ((Features.MajorVersion <= 1 && Features.MinorVersion < 6) && coinName == "Bgold")
{
coinName = "Bitcoin Gold";
}
return (await SendMessageAsync<Address, GetAddress>(new GetAddress { ShowDisplay = display, AddressNs = path, CoinName = coinName, ScriptType = inputScriptType })).address;
case AddressType.Ethereum:
var ethereumAddress = await SendMessageAsync<EthereumAddress, EthereumGetAddress>(new EthereumGetAddress { ShowDisplay = display, AddressNs = path });
var sb = new StringBuilder();
foreach (var b in ethereumAddress.Address)
{
sb.Append(b.ToString("X2").ToLower());
}
var hexString = sb.ToString();
return $"0x{hexString}";
default:
throw new NotImplementedException();
}
}
}
catch (Exception ex)
{
Logger?.Log("Error Getting Trezor Address", LogSection, ex, LogLevel.Error);
throw;
}
}
I am using active directory and want a list of all users, basically in dotnet core. But I am receiving an exception:
Search result reference received, and referral following is off
Below is my code.
LdapSearchResults lsc = lc.Search("DC = xyz, DC = local", LdapConnection.SCOPE_ONE , "(|(objectClass = person)(objectClass = user))", null, false);
Necromancing - just in case the links go dark.
To fix it in your application, set ReferralFollowing to true.
if you get the message
Search result reference received, and referral following is off
, add
Novell.Directory.Ldap.LdapSearchConstraints cons = lc.SearchConstraints;
cons.ReferralFollowing = true;
lc.Constraints = cons;
to your code.
Example:
public static void GetUsers()
{
System.Collections.Generic.List<ARSoft.Tools.Net.Dns.SrvRecord> lsLdap = GetLdap();
ARSoft.Tools.Net.Dns.SrvRecord ldap = lsLdap[0];
string[] attrs = new string[] { "cn", "distinguishedName", "sAMAccountName", "userPrincipalName", "displayName", "givenName", "sn", "mail", "mailNickname", "memberOf", "homeDirectory", "msExchUserCulture" };
// CN = Common Name
// OU = Organizational Unit
// DC = Domain Component
string searchBase = "DC=cor,DC=local";
string searchFilter = "(&(objectClass=user)(objectCategory=person))";
string ldapHost = MySamples.TestSettings.ldapHost;
int ldapPort = MySamples.TestSettings.ldapPort;//System.Convert.ToInt32(args[1]);
string loginDN = MySamples.TestSettings.loginDN; // args[2];
string password = MySamples.TestSettings.password; // args[3];
Novell.Directory.Ldap.LdapConnection lc = new Novell.Directory.Ldap.LdapConnection();
int ldapVersion = Novell.Directory.Ldap.LdapConnection.Ldap_V3;
try
{
// connect to the server
lc.Connect(ldap.Target.ToString(), ldap.Port);
// bind to the server
lc.Bind(ldapVersion, loginDN, password);
Novell.Directory.Ldap.LdapSearchConstraints cons = lc.SearchConstraints;
cons.ReferralFollowing = true;
lc.Constraints = cons;
// To enable referral following, use LDAPConstraints.setReferralFollowing passing TRUE to enable referrals, or FALSE(default) to disable referrals.
Novell.Directory.Ldap.LdapSearchResults lsc = lc.Search(searchBase,
Novell.Directory.Ldap.LdapConnection.SCOPE_SUB,
searchFilter,
attrs,
false,
(Novell.Directory.Ldap.LdapSearchConstraints)null);
while (lsc.HasMore())
{
Novell.Directory.Ldap.LdapEntry nextEntry = null;
try
{
nextEntry = lsc.Next();
}
catch (Novell.Directory.Ldap.LdapReferralException eR)
{
// https://stackoverflow.com/questions/46052873/ldap-referal-error
// The response you received means that the directory you are requesting does not contain the data you look for,
// but they are in another directory, and in the response there is the information about the "referral" directory
// on which you need to rebind to "redo" the search.This principle in LDAP are the referral.
// https://www.novell.com/documentation/developer/ldapcsharp/?page=/documentation/developer/ldapcsharp/cnet/data/bp31k5d.html
// To enable referral following, use LDAPConstraints.setReferralFollowing passing TRUE to enable referrals, or FALSE (default) to disable referrals.
// are you sure your bind user meaning
// auth.impl.ldap.userid=CN=DotCMSUser,OU=Service Accounts,DC=mycompany,DC=intranet
// auth.impl.ldap.password = mypassword123
// has permissions to the user that is logging in and its groups?
System.Diagnostics.Debug.WriteLine(eR.LdapErrorMessage);
}
catch (Novell.Directory.Ldap.LdapException e)
{
// WARNING: Here catches only LDAP-Exception, no other types...
System.Console.WriteLine("Error: " + e.LdapErrorMessage);
// Exception is thrown, go for next entry
continue;
}
var atCN = nextEntry.getAttribute("cn");
var atUN = nextEntry.getAttribute("sAMAccountName");
var atDN = nextEntry.getAttribute("distinguishedName");
var atDIN = nextEntry.getAttribute("displayName");
if (atCN != null)
System.Console.WriteLine(atCN.StringValue);
if (atUN != null)
System.Console.WriteLine(atUN.StringValue);
if (atDN != null)
System.Console.WriteLine(atDN.StringValue);
if (atDIN != null)
System.Console.WriteLine(atDIN.StringValue);
System.Console.WriteLine("\n" + nextEntry.DN);
Novell.Directory.Ldap.LdapAttributeSet attributeSet = nextEntry.getAttributeSet();
System.Collections.IEnumerator ienum = attributeSet.GetEnumerator();
while (ienum.MoveNext())
{
Novell.Directory.Ldap.LdapAttribute attribute = (Novell.Directory.Ldap.LdapAttribute)ienum.Current;
string attributeName = attribute.Name;
string attributeVal = attribute.StringValue;
System.Console.WriteLine(attributeName + "value:" + attributeVal);
}
}
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.Message);
}
finally
{
// disconnect with the server
lc.Disconnect();
}
}
You have to activate the behaviour which will follow the referral returned by the directory.
The response you received means that the directory you are requesting does not contain the data you look for, but they are in another directory, and in the response there is the information about the "referral" directory on which you need to rebind to "redo" the search. This principle in LDAP are the referral.
I don't know how to do it in C#, but maybe have a look at :
https://www.novell.com/documentation/developer/ldapcsharp/?page=/documentation/developer/ldapcsharp/cnet/data/bp31k5d.html
I'm creating an app that access the Microsoft Cloud API to get health data. It uses OAuth to log in when you hit the Sign In Button
private void signinButton_Click(object sender, RoutedEventArgs e)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_authorize.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&scope={0}", Uri.EscapeDataString(Scopes));
query.Append("&response_type=code");
uri.Query = query.ToString();
this.webView.Visibility = Visibility.Visible;
this.webView.Navigate(uri.Uri);
}
This brings up a webView with the page to log in using Microsoft credentials. Once completed, it leads to this:
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
//
// When the web view navigates to our redirect URI, extract the authorization code from
// the URI and use it to fetch our access token. If no authorization code is present,
// we're completing a sign-out flow.
//
if (args.Uri.LocalPath.StartsWith("/oauth20_desktop.srf", StringComparison.OrdinalIgnoreCase))
{
WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(args.Uri.Query);
var code = decoder.FirstOrDefault((entry) => entry.Name.Equals("code", StringComparison.OrdinalIgnoreCase));
var error = decoder.FirstOrDefault((entry) => entry.Name.Equals("error", StringComparison.OrdinalIgnoreCase));
var errorDesc = decoder.FirstOrDefault((entry) => entry.Name.Equals("error_description", StringComparison.OrdinalIgnoreCase));
// Check the code to see if this is sign-in or sign-out
if (code != null)
{
// Hide the browser again, no matter what happened...
sender.Visibility = Visibility.Collapsed;
if (error != null)
{
this.responseText.Text = string.Format("{0}\r\n{1}", error.Value, errorDesc.Value);
return;
}
var tokenError = await this.GetToken(code.Value, false);
if (string.IsNullOrEmpty(tokenError))
{
this.responseText.Text = "Successful sign-in!";
this.signoutButton.IsEnabled = true;
this.signinButton.IsEnabled = false;
this.getProfileButton.IsEnabled = true;
this.getDevicesButton.IsEnabled = true;
this.getActivitiesButton.IsEnabled = true;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = true;
}
else
{
this.responseText.Text = tokenError;
}
}
else
{
this.responseText.Text = "Successful sign-out!";
this.signoutButton.IsEnabled = false;
this.signinButton.IsEnabled = true;
this.getProfileButton.IsEnabled = false;
this.getDevicesButton.IsEnabled = false;
this.getActivitiesButton.IsEnabled = false;
this.getDailySummaryButton.IsEnabled = true;
this.getHourlySummaryButton.IsEnabled = false;
}
}
}
private async Task<string> GetToken(string code, bool isRefresh)
{
UriBuilder uri = new UriBuilder("https://login.live.com/oauth20_token.srf");
var query = new StringBuilder();
query.AppendFormat("redirect_uri={0}", Uri.EscapeDataString(RedirectUri));
query.AppendFormat("&client_id={0}", Uri.EscapeDataString(ClientId));
query.AppendFormat("&client_secret={0}", Uri.EscapeDataString(ClientSecret));
if (isRefresh)
{
query.AppendFormat("&refresh_token={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=refresh_token");
}
else
{
query.AppendFormat("&code={0}", Uri.EscapeDataString(code));
query.Append("&grant_type=authorization_code");
}
uri.Query = query.ToString();
var request = WebRequest.Create(uri.Uri);
try
{
using (var response = await request.GetResponseAsync())
{
using (var stream = response.GetResponseStream())
{
using (var streamReader = new StreamReader(stream))
{
var responseString = streamReader.ReadToEnd();
var jsonResponse = JObject.Parse(responseString);
this.creds.AccessToken = (string)jsonResponse["access_token"];
this.creds.ExpiresIn = (long)jsonResponse["expires_in"];
this.creds.RefreshToken = (string)jsonResponse["refresh_token"];
string error = (string)jsonResponse["error"];
return error;
}
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
I don't want users to have to accept the permissions every time the app is launched. Is there a way to save credentials locally so that it automatically authenticates on launch? Thanks!
You can use
Windows.Storage.ApplicationData.Current.LocalSettings
This process good described by this answer Best Way to keep Settings for a WinRT App?
The code in link identity to UWP
Store the needed oauth parts in the credential locker API. Never store these kind of information in the normal settings API.
On start read the oauth information and use the refreshtoken to get a new access token.
More Information here.
https://msdn.microsoft.com/en-us/library/windows/apps/mt270189.aspx
I am making a Bloomberg web service GetData call for the "DEBT_TO_EQUITY_FUNDAMENTALS_TKR" field. I am setting secmaster = true and asking for a single instrument with a CUSIP identifier (with yellowkey = MarketSector.Corp).
This strikes me as a fairly lightweight call having seen people asking for thousands of instruments and dozens of fields at once.
I have played around with setting lots of different settings but I just can't get this request to return in a few seconds. It gives me the correct return value but it takes longer than 60 seconds.
Any idea if it is possible to get such a request to execute and return in a few seconds?
Thanks
EDIT - Here is the code I am running:
public string GetFundamentalTicker(string identifier, InstrumentType identifierType = InstrumentType.CUSIP)
{
PerSecurityWS ps = new PerSecurityWS();
try
{
log.DebugFormat("Cert path is: {0}", CertPath);
X509Certificate2 clientCert = new X509Certificate2(CertPath, "<password_redacted>");
ps.ClientCertificates.Add(clientCert);
}
catch (Exception e)
{
log.ErrorFormat("Error in cert setup - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
//Set request header
GetDataHeaders getDataHeaders = new GetDataHeaders();
getDataHeaders.secmaster = true;
getDataHeaders.secmasterSpecified = true;
//getDataHeaders.fundamentals = true;
//getDataHeaders.fundamentalsSpecified = true;
//getDataHeaders.programflag = ProgramFlag.oneshot;//unnecessary - defaults to this anyway
//getDataHeaders.programflagSpecified = true;
//getDataHeaders.pricing = true;
getDataHeaders.secid = identifierType;
getDataHeaders.secidSpecified = true;
SubmitGetDataRequest sbmtGtDtreq = new SubmitGetDataRequest();
sbmtGtDtreq.headers = getDataHeaders;
sbmtGtDtreq.fields = new string[] {
"DEBT_TO_EQUITY_FUNDAMENTALS_TKR"
};
int currentFundYear = DateTime.Now.Year;
//var fundYears = new List<int>();
List<Instrument> fundYearInstruments = new List<Instrument>();
Instrument fundYearInstrument = null;
fundYearInstrument = new Instrument();
fundYearInstrument.id = identifier;
fundYearInstrument.typeSpecified = true;
fundYearInstrument.type = identifierType;
fundYearInstrument.yellowkey = MarketSector.Corp;
fundYearInstrument.yellowkeySpecified = true;
//fundYearInstrument.overrides = new Override[] {};//{ new Override() { field = "EQY_FUND_YEAR", value = currentFundYear.ToString() } };
fundYearInstruments.Add(fundYearInstrument);
//fundYears.Add(-1);
Instrument[] instr = fundYearInstruments.ToArray();
Instruments instrs = new Instruments();
instrs.instrument = instr;
sbmtGtDtreq.instruments = instrs;
try
{
SubmitGetDataResponse sbmtGtDtResp = ps.submitGetDataRequest(sbmtGtDtreq);
RetrieveGetDataRequest rtrvGtDrReq = new RetrieveGetDataRequest();
rtrvGtDrReq.responseId = sbmtGtDtResp.responseId;
RetrieveGetDataResponse rtrvGtDrResp;
do
{
System.Threading.Thread.Sleep(POLL_INTERVAL);
rtrvGtDrResp = ps.retrieveGetDataResponse(rtrvGtDrReq);
}
while (rtrvGtDrResp.statusCode.code == DATA_NOT_AVAILABLE);
if (rtrvGtDrResp.statusCode.code == SUCCESS)
{
for (int i = 0; i < rtrvGtDrResp.instrumentDatas.Length; i++)
{
for (int j = 0; j < rtrvGtDrResp.instrumentDatas[i].data.Length; j++)
{
if (rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.A." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.S." || rtrvGtDrResp.instrumentDatas[i].data[j].value == "N.D.")
rtrvGtDrResp.instrumentDatas[i].data[j].value = null;
return rtrvGtDrResp.instrumentDatas[i].data[j].value;
}
}
return null;
}
else if (rtrvGtDrResp.statusCode.code == REQUEST_ERROR)
{
log.ErrorFormat("Error in the submitted request: {0}", rtrvGtDrResp.statusCode.description);
return null;
}
}
catch (Exception e)
{
log.ErrorFormat("Error in GetData - {0} - {1}", e.Message, e.InnerException == null ? "" : e.InnerException.Message);
return null;
}
return null;
}
Poll interval is 5 seconds and the SOAP web service url is:
https://software.bloomberg.com/datalicensewp/dlws.wsdl
I am having the same issue. I found out that there is a difference between making the same call to Bloomberg API from, for example, console app (works very fast) and web service (takes a lot of time to start session). And the difference is that console app runs under the same user as bbcomm process, whereas web service (or actually iis process) runs under System account. You can try to log out all users on the PC where web service is hosted and then try to make the call. In this case, I guess, bbcomm goes under System account as no one else is logged in and works fast. It worked for me and the call was answered instantly.