Asp.net QBO API在同一步骤中连接和授权

Asp.net QBO API在同一步骤中连接和授权,asp.net,oauth,openid,quickbooks-online,Asp.net,Oauth,Openid,Quickbooks Online,我正在使用QBO API SDK(IppDotNetSdkQuickBooksApiV3),不知道如何允许用户连接到QuickBooks并授权我的应用程序。目前分两(2)步进行: 用户单击“连接到Intuit”并发送到Intuit登录 他们被重定向回我的应用程序,然后必须再次连接他们的实际文件 我很明显遗漏了什么,但不知道是什么。我正在使用ipp:connecttointuit功能,该功能内置于应用程序中,因此我不知道如何为我想要的结果进行自定义 我的应用程序使用上述两个步骤,但是我无法使用上面

我正在使用QBO API SDK(IppDotNetSdkQuickBooksApiV3),不知道如何允许用户连接到QuickBooks并授权我的应用程序。目前分两(2)步进行:

  • 用户单击“连接到Intuit”并发送到Intuit登录
  • 他们被重定向回我的应用程序,然后必须再次连接他们的实际文件
  • 我很明显遗漏了什么,但不知道是什么。我正在使用ipp:connecttointuit功能,该功能内置于应用程序中,因此我不知道如何为我想要的结果进行自定义

    我的应用程序使用上述两个步骤,但是我无法使用上面详述的过程在apps.com网站上列出我的应用程序。他们(apps.com)希望用户使用QBO凭据登录,授权应用程序,然后在应用程序运行时自动将用户重定向回我的网站。他们不想要重复授权(我不能责怪他们)

    完全卡住了。我是一个ok程序员,但没有OpenId或OAuth的经验


    受保护的无效页面加载(对象发送方,事件参数e)
    {
    var openIdRelyingParty=新的openIdRelyingParty();
    var openid_identifier=ConfigurationManager.AppSettings[“openid_identifier”];
    var returnUrl=“~/OpenID/Connect”;
    var response=openIdRelyingParty.GetResponse();
    如果(响应==null)
    {
    //阶段2:用户提交标识符
    标识符id;
    if(Identifier.TryParse(openid\u Identifier,out id))
    {
    IAuthenticationRequest=openIdRelyingParty.CreateRequest(openid\u标识符);
    FetchRequest fetch=新的FetchRequest();
    fetch.Attributes.Add(新的AttributeRequest(WellKnownAttributes.Contact.Email));
    fetch.Attributes.Add(新的AttributeRequest(WellKnownAttributes.Name.FullName));
    fetch.Attributes.Add(新的AttributeRequest(“http://axschema.org/intuit/realmId"));
    请求。添加扩展(获取);
    request.redirectTopProvider();
    }
    }
    其他的
    {
    if(response.FriendlyIdentifierForDisplay==null)
    {
    重定向(“~/OpenID/Connect”);
    }
    //阶段3:OpenID提供程序发送断言响应
    //会话[“FriendlyIdentifier”]=response.FriendlyIdentifierForDisplay;
    FetchResponse fetch=response.GetExtension();
    if(fetch!=null)
    {
    var openIdEmail=fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
    var openIdFullName=fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
    var openIdRealmId=fetch.GetAttributeValue(“http://axschema.org/intuit/realmId");
    字符串userName=Membership.getUsernameBayEmail(openIdEmail);
    //如果用户名为空---------------------------------------------------
    如果(用户名==null)
    {
    //DG补充道---------------------------
    字符串NewPassword=Membership.GeneratePassword(6,1);
    CreateUser(openIdEmail、NewPassword、openIdEmail);
    //DG补充道----------------------------
    //CreateUser(openIdEmail,Guid.NewGuid().ToString(),openIdEmail);
    SetAuthCookie(openIdEmail,true);
    //if(Request.QueryString[“Subscribe”!=null)
    //{
    字符串csname=“DirectConnectScript”;
    类型cstype=this.GetType();
    ClientScriptManager csm=Page.ClientScript;
    //检查启动脚本是否已注册。
    如果(!csm.isstartupscript已注册(cstype,csname))
    {
    StringBuilder cstext=新建StringBuilder();
    cstext.AppendLine(“”);
    AppendLine(“$(document).ready(函数(){”);
    cstext.AppendLine(“intuit.ipp.anywhere.directConnectToIntuit();”;
    cstext.AppendLine(“}”);”;
    cstext.AppendLine(“”);
    RegisterStartupScript(cstype,csname,cstext.ToString());
    //}
    }
    }
    else if(Request.QueryString[“Disconnect”]!=null)
    {
    clearProfile(RestProfile.GetRestProfile());
    重定向(“~/ManageConnection”);
    }
    //如果用户名不为空---------------------------------------------------
    else if(用户名!=null)
    {
    FormsAuthentication.SetAuthCookie(用户名,true);
    如果(!string.IsNullOrEmpty(returnUrl))
    {
    重定向(“~/ManageConnection”);
    }
    }
    }
    }
    }
    
    我很同情你,我自己花了一段时间才把它做好

    这是我的MVC版本。我希望有帮助

    它从QuickBooks/Index开始。使用QB弹出窗口获取我的应用程序的权限,然后从那里开始。作为奖励,如果用户已经登录到QB,如果他们过去已经授予了权限,他们将自动登录到应用程序。这是因为我将加密的令牌保存在数据库中。(忽略大部分会话。)
    protected void Page_Load(object sender, EventArgs e)
            {
                var openIdRelyingParty = new OpenIdRelyingParty();
                var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"];
                var returnUrl = "~/OpenID/Connect";
                var response = openIdRelyingParty.GetResponse();
                if (response == null)
                {
                    // Stage 2: user submitting Identifier
                    Identifier id;
                    if (Identifier.TryParse(openid_identifier, out id))
                    {
                        IAuthenticationRequest request = openIdRelyingParty.CreateRequest(openid_identifier);
                        FetchRequest fetch = new FetchRequest();
                        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
                        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
                        fetch.Attributes.Add(new AttributeRequest("http://axschema.org/intuit/realmId"));
                        request.AddExtension(fetch);
                        request.RedirectToProvider();
                    }
                }
                else
                {
                    if (response.FriendlyIdentifierForDisplay == null)
                    {
                        Response.Redirect("~/OpenID/Connect");
                    }
    
                    // Stage 3: OpenID Provider sending assertion response
                    //Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                    FetchResponse fetch = response.GetExtension<FetchResponse>();
                    if (fetch != null)
                    {
                        var openIdEmail = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
                        var openIdFullName = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
                        var openIdRealmId = fetch.GetAttributeValue("http://axschema.org/intuit/realmId");
    
                        string userName = Membership.GetUserNameByEmail(openIdEmail);
    
                        //If username is null---------------------------------------------------
                        if (userName == null)
                        {
    
                            //DG added this---------------------------
                            String NewPassword = Membership.GeneratePassword(6, 1);
                            Membership.CreateUser(openIdEmail, NewPassword, openIdEmail);
                            //DG added this----------------------------
    
                            //Membership.CreateUser(openIdEmail, Guid.NewGuid().ToString(), openIdEmail);
    
                            FormsAuthentication.SetAuthCookie(openIdEmail, true);
                            //if (Request.QueryString["Subscribe"] != null)
                            //{
                            String csname = "DirectConnectScript";
                            Type cstype = this.GetType();
                            ClientScriptManager csm = Page.ClientScript;
    
                            // Check to see if the startup script is already registered.
                            if (!csm.IsStartupScriptRegistered(cstype, csname))
                            {
                                StringBuilder cstext = new StringBuilder();
                                cstext.AppendLine("<script>");
                                cstext.AppendLine("$(document).ready(function () {");
                                cstext.AppendLine("intuit.ipp.anywhere.directConnectToIntuit();");
                                cstext.AppendLine("});");
                                cstext.AppendLine("</script>");
                                csm.RegisterStartupScript(cstype, csname, cstext.ToString());
                                //}
                            }
    
                        }
                        else if (Request.QueryString["Disconnect"] != null)
                        {
                            RestHelper.clearProfile(RestProfile.GetRestProfile());
                            Response.Redirect("~/ManageConnection");
                        }
    
                        //If username is not null---------------------------------------------------
                        else if (userName != null)
                        {
                            FormsAuthentication.SetAuthCookie(userName, true);
    
                            if (!string.IsNullOrEmpty(returnUrl))
                            {
                                Response.Redirect("~/ManageConnection");
                            }
                        }
                    }
    
                }
            }
    
    public class OauthResponseController : Controller
    {
        /// <summary>
        /// OAuthVerifyer, RealmId, DataSource
        /// </summary>
        private String _oauthVerifyer, _realmid, _dataSource;
    
        /// <summary>
        /// Action Results for Index, OAuthToken, OAuthVerifyer and RealmID is recieved as part of Response
        /// and are stored inside Session object for future references
        /// NOTE: Session storage is only used for demonstration purpose only.
        /// </summary>
        /// <returns>View Result.</returns>
        public ViewResult Index()
        {
            if (Request.QueryString.HasKeys())
            {
                // This value is used to Get Access Token.
                _oauthVerifyer = Request.QueryString.GetValues("oauth_verifier").FirstOrDefault().ToString();
                if (_oauthVerifyer.Length == 1)
                {
                    _oauthVerifyer = Request.QueryString["oauth_verifier"].ToString();
                }
                _realmid = Request.QueryString.GetValues("realmId").FirstOrDefault().ToString();
                if (_realmid.Length == 1)
                {
                    _realmid = Request.QueryString["realmId"].ToString();
                }
                Session["Realm"] = _realmid;
    
                //If dataSource is QBO call QuickBooks Online Services, else call QuickBooks Desktop Services
                _dataSource = Request.QueryString.GetValues("dataSource").FirstOrDefault().ToString();
                if (_dataSource.Length == 1)
                {
                    _dataSource = Request.QueryString["dataSource"].ToString();
                }
                Session["DataSource"] = _dataSource;
    
                getAccessToken();
    
    
                //Production applications should securely store the Access Token.
                //In this template, encrypted Oauth access token is persisted in OauthAccessTokenStorage.xml
                OauthAccessTokenStorageHelper.StoreOauthAccessToken();
    
                // This value is used to redirect to Default.aspx from Cleanup page when user clicks on ConnectToInuit widget.
                Session["RedirectToDefault"] = true;
            }
            else
            {
                Response.Write("No oauth token was received");
            }
    
            return View(); // This will redirect to /QuickBooks/OpenIdIndex which is almost the same as the code that you have posted
        }
    
        /// <summary>
        /// Gets the OAuth Token
        /// </summary>
        private void getAccessToken()
        {
            IOAuthSession clientSession = CreateSession();
            try
            {
                IToken accessToken = clientSession.ExchangeRequestTokenForAccessToken((IToken)Session["requestToken"], _oauthVerifyer);
                Session["AccessToken"] = accessToken.Token;
    
                // Add flag to session which tells that accessToken is in session
                Session["Flag"] = true;
    
                // Remove the Invalid Access token since we got the new access token
                Session.Remove("InvalidAccessToken");
                Session["AccessTokenSecret"] = accessToken.TokenSecret;
            }
            catch (Exception ex)
            {
                //Handle Exception if token is rejected or exchange of Request Token for Access Token failed.
                throw ex;
            }
    
        }
    
        /// <summary>
        /// Creates User Session
        /// </summary>
        /// <returns>OAuth Session.</returns>
        private IOAuthSession CreateSession()
        {
            OAuthConsumerContext consumerContext = new OAuthConsumerContext
            {
                ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
                ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString(),
                SignatureMethod = SignatureMethod.HmacSha1
            };
    
            return new OAuthSession(consumerContext,
                                            Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
                                            Constants.OauthEndPoints.IdFedOAuthBaseUrl,
                                             Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
        }
    }
    
    public class QuickBooksController : Controller
    {
        private readonly IQueryChannel _queryChannel;
        private readonly ICommandChannel _commandChannel;
        public QuickBooksController(IQueryChannel queryChannel, ICommandChannel commandChannel)
        {
            _queryChannel = queryChannel;
            _commandChannel = commandChannel;
        }
        /// <summary>
        /// OpenId Relying Party
        /// </summary>
        private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
    
        public ActionResult Index(string returnurl)
        {
            QuickBooksAuthStore.Load();
            if (QuickBooksContext.AccessToken != null)
            {
                if (!new Customers().CheckConnection())
                {
                    QuickBooksContext.FriendlyName = null;
                    OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(QuickBooksContext.FriendlyEmail);
                    QuickBooksContext.AccessToken = null;
                }
            }
            if (returnurl != null || QuickBooksContext.QuickReturnUrl != null)
            {
                if (returnurl != null)
                {
                   QuickBooksContext.QuickReturnUrl = returnurl; 
                }
                if (QuickBooksContext.AccessToken != null)
                {
                    var connected = new Customers().CheckConnection();
                    if (connected)
                    {
                        returnurl = QuickBooksContext.QuickReturnUrl;
                        QuickBooksContext.QuickReturnUrl = null;
                        return Redirect(returnurl);
                    }
                }  
            }
            return View();
        }
    
        public RedirectResult OpenIdIndex()
        {
            var openid_identifier = ConfigurationManager.AppSettings["openid_identifier"] + SessionContext.CurrentUser.MasterCompanyId;
            var response = openid.GetResponse();
            if (response == null)
            {
                // Stage 2: user submitting Identifier
                Identifier id;
                if (Identifier.TryParse(openid_identifier, out id))
                {
                    try
                    {
                        IAuthenticationRequest request = openid.CreateRequest(openid_identifier);
                        FetchRequest fetch = new FetchRequest();
                        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email));
                        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.FullName));
                        request.AddExtension(fetch);
                        request.RedirectToProvider();
                    }
                    catch (ProtocolException ex)
                    {
                        throw ex;
                    }
                }
            }
            else
            {
                if (response.FriendlyIdentifierForDisplay == null)
                {
                    Response.Redirect("/OpenId");
                }
    
                // Stage 3: OpenID Provider sending assertion response, storing the response in Session object is only for demonstration purpose
                Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                FetchResponse fetch = response.GetExtension<FetchResponse>();
                if (fetch != null)
                {
                    Session["OpenIdResponse"] = "True";
                    Session["FriendlyEmail"] = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);// emailAddresses.Count > 0 ? emailAddresses[0] : null;
                    Session["FriendlyName"] = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);//fullNames.Count > 0 ? fullNames[0] : null;
    
                    OauthAccessTokenStorageHelper.GetOauthAccessTokenForUser(Session["FriendlyEmail"].ToString());
                    QuickBooksAuthStore.UpdateFriendlyId(Session["FriendlyIdentifier"].ToString(), Session["FriendlyName"].ToString());
                }
            }
    
            string query = Request.Url.Query;
            if (!string.IsNullOrWhiteSpace(query) && query.ToLower().Contains("disconnect=true"))
            {
                Session["AccessToken"] = "dummyAccessToken";
                Session["AccessTokenSecret"] = "dummyAccessTokenSecret";
                Session["Flag"] = true;
                return Redirect("QuickBooks/CleanupOnDisconnect");
            }
            return Redirect("/QuickBooks/Index");
        }
    
        /// <summary>
        /// Service response.
        /// </summary>
        private String txtServiceResponse = "";
    
        /// <summary>
        /// Disconnect Flag.
        /// </summary>
        protected String DisconnectFlg = "";
        public ActionResult Disconnect()
        {
            OAuthConsumerContext consumerContext = new OAuthConsumerContext
            {
                ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
                SignatureMethod = SignatureMethod.HmacSha1,
                ConsumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString()
            };
    
            OAuthSession oSession = new OAuthSession(consumerContext, Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
                                  Constants.OauthEndPoints.AuthorizeUrl,
                                  Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
    
            oSession.ConsumerContext.UseHeaderForOAuthParameters = true;
            if ((Session["AccessToken"] + "").Length > 0)
            {
                Session["FriendlyName"] = null;
                oSession.AccessToken = new TokenBase
                {
                    Token = Session["AccessToken"].ToString(),
                    ConsumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString(),
                    TokenSecret = Session["AccessTokenSecret"].ToString()
                };
    
                IConsumerRequest conReq = oSession.Request();
                conReq = conReq.Get();
                conReq = conReq.ForUrl(Constants.IaEndPoints.DisconnectUrl);
                try
                {
                    conReq = conReq.SignWithToken();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
                //Used just see the what header contains
                string header = conReq.Context.GenerateOAuthParametersForHeader();
    
                //This method will clean up the OAuth Token
                txtServiceResponse = conReq.ReadBody();
    
                //Reset All the Session Variables
                Session.Remove("oauthToken");
    
                // Dont remove the access token since this is required for Reconnect btn in the Blue dot menu
                // Session.Remove("accessToken");
    
                // Add the invalid access token into session for the display of the Disconnect btn
                Session["InvalidAccessToken"] = Session["AccessToken"];
    
                // Dont Remove flag since we need to display the blue dot menu for Reconnect btn in the Blue dot menu
                // Session.Remove("Flag");
    
                ViewBag.DisconnectFlg = "User is Disconnected from QuickBooks!";
    
                //Remove the Oauth access token from the OauthAccessTokenStorage.xml
                OauthAccessTokenStorageHelper.RemoveInvalidOauthAccessToken(Session["FriendlyEmail"].ToString());
            }
    
            return RedirectToAction("Index", "QuickBooks");
        }
    
        public ActionResult CleanUpOnDisconnect()
        {
            //perform the clean up here 
    
            // Redirect to Home when user clicks on ConenctToIntuit widget.
            object value = Session["RedirectToDefault"];
            if (value != null)
            {
                bool isTrue = (bool)value;
                if (isTrue)
                {
                    Session.Remove("InvalidAccessToken");
                    Session.Remove("RedirectToDefault");
                    return Redirect("/QuickBooks/index");
                }
            }
    
            return RedirectToAction("Index", "QuickBooks");
        }
    
        private String consumerSecret, consumerKey, oauthLink, RequestToken, TokenSecret, oauth_callback_url;
    
        public RedirectResult OAuthGrant()
        {
            oauth_callback_url = Request.Url.GetLeftPart(UriPartial.Authority) + ConfigurationManager.AppSettings["oauth_callback_url"];
            consumerKey = ConfigurationManager.AppSettings["consumerKey"];
            consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
            oauthLink = Constants.OauthEndPoints.IdFedOAuthBaseUrl;
            IToken token = (IToken)Session["requestToken"];
            IOAuthSession session = CreateSession();
            IToken requestToken = session.GetRequestToken();
            Session["requestToken"] = requestToken;
            RequestToken = requestToken.Token;
            TokenSecret = requestToken.TokenSecret;
    
            oauthLink = Constants.OauthEndPoints.AuthorizeUrl + "?oauth_token=" + RequestToken + "&oauth_callback=" + UriUtility.UrlEncode(oauth_callback_url);
            return Redirect(oauthLink);
        }
    
        /// <summary>
        /// Gets the Access Token
        /// </summary>
        /// <returns>Returns OAuth Session</returns>
        protected IOAuthSession CreateSession()
        {
            OAuthConsumerContext consumerContext = new OAuthConsumerContext
            {
                ConsumerKey = consumerKey,
                ConsumerSecret = consumerSecret,
                SignatureMethod = SignatureMethod.HmacSha1
            };
    
            return new OAuthSession(consumerContext,
                                            Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlRequestToken,
                                            oauthLink,
                                            Constants.OauthEndPoints.IdFedOAuthBaseUrl + Constants.OauthEndPoints.UrlAccessToken);
        }
    }
    
    @using System.Configuration
    @using PubManager.Domain.WebSession
    @{
        string MenuProxy = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["menuProxy"];
        string OauthGrant = Request.Url.GetLeftPart(UriPartial.Authority) + "/" + System.Configuration.ConfigurationManager.AppSettings["grantUrl"];
    
        ViewBag.Title = "MagManager - Intuit Anywhere";
        string FriendlyName = (string)HttpContext.Current.Session["FriendlyName"] + "";
        string FriendlyEmail = (string)HttpContext.Current.Session["FriendlyEmail"];
        string FriendlyIdentifier = (string)HttpContext.Current.Session["FriendlyIdentifier"];
    
        string realm = (string)Session["Realm"];
        string dataSource = (string)Session["DataSource"];
        string accessToken = (string)Session["AccessToken"] + "";
        string accessTokenSecret = (string)Session["AccessTokenSecret"];
        string invalidAccessToken = (string)Session["InvalidAccessToken"];
    }
    
    <h1>Intuit - QuickBooks Online</h1>
    
    <div class="well">
        @if (FriendlyName.Length == 0)
        {
            <script>
                window.location.href = "/QuickBooks/OpenIdIndex";
            </script>
        }
        else
        {
            <div id="IntuitInfo">
                <strong>Open Id Information:</strong><br />
                Welcome: @FriendlyName<br />
                E-mail Address: @FriendlyEmail<br />
                <br />
                @if (accessToken.Length > 0 && invalidAccessToken == null)
                {
                    <div id="oAuthinfo">
                        <a onclick="reconcileInvoices()" id="RecInvoices" class="btn btn-primary">Set Invoices Paid</a><br />
                        <br/>
                        <a onclick="recTax()" id="RecTax" class="btn btn-primary">Sync Tax Rates</a><br />
                        <br/>
                        @if (SessionContext.UseAccountCodes)
                        {
                            <a onclick="recProducts()" id="RecProducts" class="btn btn-primary">Sync Products</a><br />
                            <br />
                        }
                        <a href="/QuickBooks/ReconcileCustomers" id="Customers" class="btn btn-primary">Reconcile Customers</a><br/>
                        <br/>
                        <a href="/QuickBooks/Disconnect" id="Disconnect" class="btn btn-primary">
                            Disconnect from
                            QuickBooks
                        </a>
                        <br/><br/>
                        @*<a href="/QuickBooks/Customers" id="QBCustomers" class="btn btn-primary">Get QuickBooks Customer List</a><br/>
            <br/>*@
    
                        @*<br />
            <a href="/QuickBooks/Invoices" id="QBInvoices" class="btn btn-primary">Get QuickBooks Invoice List</a><br />
            <br />*@
                        <br />
                    </div>
                }
                else
                {
                    <br />
                        <ipp:connecttointuit></ipp:connecttointuit>
                }
            </div>
        }
    </div>
    <script type="text/javascript" src="https://js.appcenter.intuit.com/Content/IA/intuit.ipp.anywhere-1.3.5.js"></script>
    <script type="text/javascript">
        intuit.ipp.anywhere.setup({
            menuProxy: '@MenuProxy',
            grantUrl: '@OauthGrant'
        });
    </script>