使用C# 与Xero OAuth 交互 集成

来源:互联网 发布:nginx 404 编辑:程序博客网 时间:2024/06/05 15:54
本文主要介绍和xero OAuth的集成过程,以后再与其他第三方的OAuth的集成过程也将类似。 另外由于xero官方的文档非常有限,因此有必要进行总结一下。
Xero 是一个财务系统,可用于替代产品账单模块的实现。
www.xero.com


了解OAuth :


http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

http://baike.baidu.com/view/6619164.htm


概括起来就是,对于SystemA用户要访问systemB的资源,sysB的用户可以指定将SysB中的哪些部分(模块)暴露出来给SysA进行访问,同时会给sysA一个token和证书。每次sysA访问sysB时需要带上token以及证书。


1. 安装 nuget pkg :


2. 创建wapper 来封装交互过程


前提:
1.需要已经安装证书
2.已经得到了key/secret







public class XeroApiAdapter    {        private readonly IXeroApiParameter _parameter;        private const string PARTNER_URL = "https://api-partner.network.xero.com";        private const string BASE_URL = "https://api.xero.com";        public XeroCoreApi CoreApi { get; private set; }        private readonly X509Certificate2 _signingCertificate;        private readonly X509Certificate2 _partnerCertificate;        /// <summary>        ///         /// </summary>        /// <param name="parameter"></param>        public XeroApiAdapter(IXeroApiParameter parameter)        {            _signingCertificate = XeroOAuthSettings.Fetch.SigningCertificate.SelectedCertificate;            if (_signingCertificate == null)            {                throw new Exception("Signing certificate must be defined");            }            _partnerCertificate = XeroOAuthSettings.Fetch.PartnerCertificate.SelectedCertificate;            if (_partnerCertificate == null)            {                throw new Exception("partner certificate must be defined");            }            _parameter = parameter;            var user = new ApiUser { OrganisationId = parameter.NetworkId, Name = parameter.NetworkId };            CoreApi = new XeroCoreApi(PARTNER_URL,            new RuPartnerAuthethicator(PARTNER_URL, BASE_URL, XeroTokenServices.Do,                _signingCertificate, _partnerCertificate),            new Consumer(parameter.ConsumerKey, parameter.ConsumerSecret), user,            new DefaultMapper(), new DefaultMapper());        }        public PartnerMvcAuthenticator MvcAuthenticator(string callBack)        {            return new PartnerMvcAuthenticator(PARTNER_URL, BASE_URL, callBack, XeroTokenServices.Do,                _signingCertificate, _partnerCertificate,                new Consumer(_parameter.ConsumerKey, _parameter.ConsumerSecret),                XeroRequestTokenServices.Do);        }            }






RuPartnerAuthethicator.cs (主要用于over write xero de AuthorizeUser函数,默认会打开浏览器):







public class RuPartnerAuthethicator : PartnerAuthenticator    {        public RuPartnerAuthethicator(string baseUri, string authorizeUri, ITokenStore store, string signingCertificatePath, string certificatePath, string password) : base(baseUri, authorizeUri, "", store, signingCertificatePath, certificatePath, password)        {        }        public RuPartnerAuthethicator(string baseUri, string authorizeUri, ITokenStore store, X509Certificate2 signingCertificate, X509Certificate2 certificate) : base(baseUri, authorizeUri, "", store, signingCertificate, certificate)        {        }        protected override string AuthorizeUser(IToken token)        {            throw new XeroRenewAccessTokenException("Please renew access token");        }    }




3. 实现IToken 接口,分为Request Token和 Access Token。 即请求token和访问token,访问token需要做持久化,请求token可存内存中。







 public class XeroTokenServices : MongoService, ITokenStore    {        public static XeroTokenServices Do        {            get            {                return new XeroTokenServices();            }        }        private XeroTokenServices()        {        }        private MongoCollection<MDXeroToken> XeroTokenStore        {            get            {                return Connection.GetMongoCollection<MDXeroToken>("XeroTokenStore");            }        }        public void Add(IToken token)        {            //Lets delete first as we are not sure if Xero have a delete            Delete(token);            XeroTokenStore.Save(new MDXeroToken(token));        }        public void Delete(IToken token)        {            XeroTokenStore.Remove(Query<MDXeroToken>.EQ(x => x.UserId, token.UserId));        }        public IToken Find(string user)        {            var token = XeroTokenStore.FindOne(Query<MDXeroToken>.EQ(x => x.UserId, user));                        return token;        }        public void ClearTokenForNetwork(string id)        {            XeroTokenStore.Remove(Query<MDXeroToken>.EQ(x => x.UserId, id));        }    }    public class XeroRequestTokenServices : MongoService, ITokenStore    {        public static XeroRequestTokenServices Do        {            get { return new XeroRequestTokenServices(); }        }        private XeroRequestTokenServices()        {        }        private MongoCollection<MDXeroToken> XeroTokenStore        {            get            {                return Connection.GetMongoCollection<MDXeroToken>("XeroRequestTokenStore");            }        }        public void Add(IToken token)        {            //Lets delete first as we are not sure if Xero have a delete            Delete(token);            XeroTokenStore.Save(new MDXeroToken(token));        }        public void Delete(IToken token)        {            XeroTokenStore.Remove(Query<MDXeroToken>.EQ(x => x.UserId, token.UserId));        }        public IToken Find(string user)        {            return XeroTokenStore.FindOne(Query<MDXeroToken>.EQ(x => x.UserId, user));        }        public void ClearTokenForNetwork(string id)        {            XeroTokenStore.Remove(Query<MDXeroToken>.EQ(x => x.UserId, id));        }    }




4. 指定callback 函数, 在xero配置callback domain

4.1 添加Application 


4.2  配置call back domain , 生成key , secret


4.3 Call back 函数:


public ActionResult Authorize(string oauth_token, string oauth_verifier, string org, string redirect)        {            var network = NetworksManagment.Do.GetNetwork(Tenant.NetworkId);            var xeroApi = new XeroApiAdapter(new XeroApiParam(network));            var authenthicator = xeroApi.MvcAuthenticator("");            try            {                // - call XeroTokenServices.Add and store the token in MDXeroToken                var token = authenthicator.RetrieveAndStoreAccessToken(network.Id, oauth_token, oauth_verifier, org);                var organization = xeroApi.CoreApi.Organisation;                ...                TempData.AddNotification(NotifcationType.Success, "Xero connected successfully");            }            catch (Exception ex)            {                TempData.AddNotification("Error connecting to Xero", ex);            }            if (string.IsNullOrEmpty(redirect))            {                return RedirectToAction("Index");            }                        return Redirect(redirect);        }



xero 官方 git:


https://github.com/XeroAPI/Xero-Net
1 0