Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converted AuthClient to work with .net core #18

Open
MarkOates71 opened this issue Aug 6, 2019 · 2 comments
Open

Converted AuthClient to work with .net core #18

MarkOates71 opened this issue Aug 6, 2019 · 2 comments

Comments

@MarkOates71
Copy link

I've rewritten the AuthClient class to work with .net core but run into an issue with the cert, the problem I have is I'm seeing a betfair response of CERT_AUTH_REQUIRED

I'm newish to c#/ .net core so any help would be appreciated, and once working i'll post the code here

thanks
Mark

@bitcoinbrisbane
Copy link

bitcoinbrisbane commented Aug 13, 2019

I have just done the same thing, where did you get stuck? The below returns a session id so from there you should be good.

Make sure you've uploaded your .pfx to betfair and allowed cert auth.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Betting.Models.Betfair;
using Newtonsoft.Json;

namespace Betting
{
    public class BaseBetfairClient
    {
        public const string APPKEY_HEADER = "X-Application";
        public const string SESSION_TOKEN_HEADER = "X-Authentication";

        private static readonly string LIST_EVENT_TYPES_METHOD = "SportsAPING/v1.0/listEventTypes";
        private static readonly string LIST_MARKET_TYPES_METHOD = "SportsAPING/v1.0/listMarketTypes";
        private static readonly string LIST_MARKET_CATALOGUE_METHOD = "SportsAPING/v1.0/listMarketCatalogue";
        private static readonly string LIST_MARKET_BOOK_METHOD = "SportsAPING/v1.0/listMarketBook";
        private static readonly string PLACE_ORDERS_METHOD = "SportsAPING/v1.0/placeOrders";
        private static readonly string LIST_MARKET_PROFIT_AND_LOST_METHOD = "SportsAPING/v1.0/listMarketProfitAndLoss";
        private static readonly string LIST_CURRENT_ORDERS_METHOD = "SportsAPING/v1.0/listCurrentOrders";
        private static readonly string LIST_CLEARED_ORDERS_METHOD = "SportsAPING/v1.0/listClearedOrders";
        private static readonly string CANCEL_ORDERS_METHOD = "SportsAPING/v1.0/cancelOrders";
        private static readonly string REPLACE_ORDERS_METHOD = "SportsAPING/v1.0/replaceOrders";
        private static readonly string UPDATE_ORDERS_METHOD = "SportsAPING/v1.0/updateOrders";
        private static readonly String FILTER = "filter";
        private static readonly String LOCALE = "locale";
        private static readonly String CURRENCY_CODE = "currencyCode";
        private static readonly String MARKET_PROJECTION = "marketProjection";
        private static readonly String MATCH_PROJECTION = "matchProjection";
        private static readonly String ORDER_PROJECTION = "orderProjection";
        private static readonly String PRICE_PROJECTION = "priceProjection";
        private static readonly String SORT = "sort";
        private static readonly String MAX_RESULTS = "maxResults";
        private static readonly String MARKET_IDS = "marketIds";
        private static readonly String MARKET_ID = "marketId";
        private static readonly String INSTRUCTIONS = "instructions";
        private static readonly String CUSTOMER_REFERENCE = "customerRef";
        private static readonly String INCLUDE_SETTLED_BETS = "includeSettledBets";
        private static readonly String INCLUDE_BSP_BETS = "includeBspBets";
        private static readonly String NET_OF_COMMISSION = "netOfCommission";
        private static readonly String BET_IDS = "betIds";
        private static readonly String PLACED_DATE_RANGE = "placedDateRange";
        private static readonly String ORDER_BY = "orderBy";
        private static readonly String SORT_DIR = "sortDir";
        private static readonly String FROM_RECORD = "fromRecord";
        private static readonly String RECORD_COUNT = "recordCount";
        private static readonly string BET_STATUS = "betStatus";
        private static readonly string EVENT_TYPE_IDS = "eventTypeIds";
        private static readonly string EVENT_IDS = "eventIds";
        private static readonly string RUNNER_IDS = "runnerIds";
        private static readonly string SIDE = "side";
        private static readonly string SETTLED_DATE_RANGE = "settledDateRange";
        private static readonly string GROUP_BY = "groupBy";
        private static readonly string INCLUDE_ITEM_DESCRIPTION = "includeItemDescription";

        private string appKey = "xxx";

        private string sessionToken;

        private const string DEFAULT_COM_BASEURL = "https://identitysso-cert.betfair.com";

        public async Task<LoginResponse> doLogin(string username, string password, string certFilename)
        {
            if (File.Exists(certFilename))
            {
                var client = initHttpClientInstance(appKey);
                var content = getLoginBodyAsContent(username, password);
                var result = await client.PostAsync(DEFAULT_COM_BASEURL + "/api/certlogin", content);
                result.EnsureSuccessStatusCode();

                string _content = await result.Content.ReadAsStringAsync();

                LoginResponse loginResponse = JsonConvert.DeserializeObject<LoginResponse>(_content);
                return loginResponse;
            }
            else
            {
                throw new FileNotFoundException(certFilename);
            }
        }

        public HttpClient initHttpClientInstance(string appKey, string baseUrl = DEFAULT_COM_BASEURL)
        {
            var cert = new X509Certificate2("xxx.pfx", "xxx");
            var clientHandler = new HttpClientHandler();
            clientHandler.ClientCertificates.Add(cert);
            
            var client = new HttpClient(clientHandler);
            client.BaseAddress = new Uri(baseUrl);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Add("X-Application", appKey);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            return client;
        }

        private FormUrlEncodedContent getLoginBodyAsContent(string username, string password)
        {
            var postData = new List<KeyValuePair<string, string>>();
            postData.Add(new KeyValuePair<string, string>("username", username));
            postData.Add(new KeyValuePair<string, string>("password", password));
            return new FormUrlEncodedContent(postData);
        }
    }
}

@MarkOates71
Copy link
Author

I fixed this the day after posting but didn't get chance to post my solution which is more aligned to the original code, see below, I did already have cert uploaded to Betfair. I ended up replacing the method getWebRequestHandlerWithCert with one of my own (which references HttpClientHandler instead of WebRequestHandler) called GetHttpClient

Original Code
private WebRequestHandler getWebRequestHandlerWithCert (string certFilename)
{
var cert = new X509Certificate2(certFilename, "");

        var clientHandler = new WebRequestHandler();
        clientHandler.ClientCertificates.Add(cert);
        return clientHandler;
    }

Changed to.....

private HttpClientHandler GetHttpClient(X509Certificate2 certData)
{

        //specify to use TLS 1.2 as default connection
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        var clientHandler = new HttpClientHandler();

        clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
        clientHandler.SslProtocols = SslProtocols.Tls12;

        X509Certificate2 newCert = new X509Certificate2(certData);
        clientHandler.ClientCertificates.Add(newCert);
        return clientHandler;

    }

Let me know if you try this out
Mark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants