diff options
Diffstat (limited to 'samples/OAuthServiceProvider')
10 files changed, 287 insertions, 25 deletions
diff --git a/samples/OAuthServiceProvider/App_Code/CustomOAuthTypeProvider.cs b/samples/OAuthServiceProvider/App_Code/CustomOAuthTypeProvider.cs index 9fdbf29..0932dec 100644 --- a/samples/OAuthServiceProvider/App_Code/CustomOAuthTypeProvider.cs +++ b/samples/OAuthServiceProvider/App_Code/CustomOAuthTypeProvider.cs @@ -15,7 +15,8 @@ public class CustomOAuthMessageFactory : OAuthServiceProviderMessageFactory { /// Initializes a new instance of the <see cref="CustomOAuthMessageFactory"/> class. /// </summary> /// <param name="tokenManager">The token manager instance to use.</param> - public CustomOAuthMessageFactory(IServiceProviderTokenManager tokenManager) : base(tokenManager) { + public CustomOAuthMessageFactory(IServiceProviderTokenManager tokenManager) + : base(tokenManager) { } public override IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) { @@ -23,7 +24,7 @@ public class CustomOAuthMessageFactory : OAuthServiceProviderMessageFactory { // inject our own type here to replace the standard one if (message is UnauthorizedTokenRequest) { - message = new RequestScopedTokenMessage(recipient); + message = new RequestScopedTokenMessage(recipient, message.Version); } return message; diff --git a/samples/OAuthServiceProvider/App_Code/DataClasses.dbml b/samples/OAuthServiceProvider/App_Code/DataClasses.dbml index 0b54d0d..78518c2 100644 --- a/samples/OAuthServiceProvider/App_Code/DataClasses.dbml +++ b/samples/OAuthServiceProvider/App_Code/DataClasses.dbml @@ -25,6 +25,9 @@ <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" /> <Column Name="ConsumerKey" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" /> <Column Name="ConsumerSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" /> + <Column Member="Callback" Type="System.String" CanBeNull="true" /> + <Column Member="VerificationCodeFormat" Type="DotNetOpenAuth.OAuth.VerificationCodeFormat" CanBeNull="false" /> + <Column Member="VerificationCodeLength" Type="System.Int32" CanBeNull="false" /> <Association Name="OAuthConsumer_OAuthToken" Member="OAuthTokens" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthToken" /> </Type> </Table> @@ -33,11 +36,14 @@ <Column Name="TokenId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" /> <Column Name="Token" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" /> <Column Name="TokenSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" /> - <Column Name="State" Type="TokenAuthorizationState" DbType="Int NOT NULL" CanBeNull="false" /> + <Column Name="State" Type="TokenAuthorizationState" DbType="INT NOT NULL" CanBeNull="false" /> <Column Name="IssueDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" /> <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" /> <Column Name="UserId" Type="System.Int32" DbType="Int" CanBeNull="true" /> <Column Name="Scope" Type="System.String" DbType="nvarchar(MAX)" CanBeNull="false" /> + <Column Name="RequestTokenVerifier" Type="System.String" CanBeNull="true" /> + <Column Name="RequestTokenCallback" Type="System.String" CanBeNull="true" /> + <Column Name="ConsumerVersion" Type="System.String" CanBeNull="true" /> <Association Name="OAuthConsumer_OAuthToken" Member="OAuthConsumer" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthConsumer" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" /> <Association Name="User_OAuthToken" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" /> </Type> diff --git a/samples/OAuthServiceProvider/App_Code/DataClasses.dbml.layout b/samples/OAuthServiceProvider/App_Code/DataClasses.dbml.layout index 1fc61cf..71bd4aa 100644 --- a/samples/OAuthServiceProvider/App_Code/DataClasses.dbml.layout +++ b/samples/OAuthServiceProvider/App_Code/DataClasses.dbml.layout @@ -14,16 +14,16 @@ <elementListCompartment Id="eba736b9-f9ec-484b-8083-c77155a49e4e" absoluteBounds="3.515, 1.085, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> </nestedChildShapes> </classShape> - <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.625, 3.25, 2, 1.3862939453124998"> + <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.625, 3.25, 2, 1.9631982421874996"> <DataClassMoniker Name="/DataClassesDataContext/OAuthConsumer" /> <nestedChildShapes> - <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.64, 3.71, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.64, 3.71, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> </nestedChildShapes> </classShape> - <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 2.3478011067708326"> + <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 2.9247054036458326"> <DataClassMoniker Name="/DataClassesDataContext/OAuthToken" /> <nestedChildShapes> - <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 1.7878011067708333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> + <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" /> </nestedChildShapes> </classShape> <associationConnector edgePoints="[(2.625 : 1.31814697265625); (3.5 : 1.31814697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed"> @@ -33,14 +33,14 @@ <classShapeMoniker Id="8a79b099-7f87-4766-907a-db2c3e1b5716" /> </nodes> </associationConnector> - <associationConnector edgePoints="[(2.625 : 3.94314697265625); (3.5 : 3.94314697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm"> + <associationConnector edgePoints="[(2.625 : 4.23159912109375); (3.5 : 4.23159912109375)]" fixedFrom="Algorithm" fixedTo="Algorithm"> <AssociationMoniker Name="/DataClassesDataContext/OAuthConsumer/OAuthConsumer_OAuthToken" /> <nodes> <classShapeMoniker Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" /> <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" /> </nodes> </associationConnector> - <associationConnector edgePoints="[(0.53125 : 2.27089680989583); (0.53125 : 5.08579752604167); (3.5 : 5.08579752604167)]" fixedFrom="Algorithm" fixedTo="Algorithm"> + <associationConnector edgePoints="[(0.53125 : 2.27089680989583); (0.53125 : 5.66270182291667); (3.5 : 5.66270182291667)]" fixedFrom="Algorithm" fixedTo="Algorithm"> <AssociationMoniker Name="/DataClassesDataContext/User/User_OAuthToken" /> <nodes> <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" /> diff --git a/samples/OAuthServiceProvider/App_Code/DataClasses.designer.cs b/samples/OAuthServiceProvider/App_Code/DataClasses.designer.cs index 2fc532e..b66e75f 100644 --- a/samples/OAuthServiceProvider/App_Code/DataClasses.designer.cs +++ b/samples/OAuthServiceProvider/App_Code/DataClasses.designer.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:2.0.50727.3053 +// Runtime Version:2.0.50727.4918 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -483,6 +483,12 @@ public partial class OAuthConsumer : INotifyPropertyChanging, INotifyPropertyCha private string _ConsumerSecret; + private string _Callback; + + private DotNetOpenAuth.OAuth.VerificationCodeFormat _VerificationCodeFormat; + + private int _VerificationCodeLength; + private EntitySet<OAuthToken> _OAuthTokens; #region Extensibility Method Definitions @@ -495,6 +501,12 @@ public partial class OAuthConsumer : INotifyPropertyChanging, INotifyPropertyCha partial void OnConsumerKeyChanged(); partial void OnConsumerSecretChanging(string value); partial void OnConsumerSecretChanged(); + partial void OnCallbackChanging(string value); + partial void OnCallbackChanged(); + partial void OnVerificationCodeFormatChanging(DotNetOpenAuth.OAuth.VerificationCodeFormat value); + partial void OnVerificationCodeFormatChanged(); + partial void OnVerificationCodeLengthChanging(int value); + partial void OnVerificationCodeLengthChanged(); #endregion public OAuthConsumer() @@ -563,6 +575,66 @@ public partial class OAuthConsumer : INotifyPropertyChanging, INotifyPropertyCha } } + [Column(Storage="_Callback")] + public string Callback + { + get + { + return this._Callback; + } + set + { + if ((this._Callback != value)) + { + this.OnCallbackChanging(value); + this.SendPropertyChanging(); + this._Callback = value; + this.SendPropertyChanged("Callback"); + this.OnCallbackChanged(); + } + } + } + + [Column(Storage="_VerificationCodeFormat")] + public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat + { + get + { + return this._VerificationCodeFormat; + } + set + { + if ((this._VerificationCodeFormat != value)) + { + this.OnVerificationCodeFormatChanging(value); + this.SendPropertyChanging(); + this._VerificationCodeFormat = value; + this.SendPropertyChanged("VerificationCodeFormat"); + this.OnVerificationCodeFormatChanged(); + } + } + } + + [Column(Storage="_VerificationCodeLength")] + public int VerificationCodeLength + { + get + { + return this._VerificationCodeLength; + } + set + { + if ((this._VerificationCodeLength != value)) + { + this.OnVerificationCodeLengthChanging(value); + this.SendPropertyChanging(); + this._VerificationCodeLength = value; + this.SendPropertyChanged("VerificationCodeLength"); + this.OnVerificationCodeLengthChanged(); + } + } + } + [Association(Name="OAuthConsumer_OAuthToken", Storage="_OAuthTokens", ThisKey="ConsumerId", OtherKey="ConsumerId")] public EntitySet<OAuthToken> OAuthTokens { @@ -631,6 +703,12 @@ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChange private string _Scope; + private string _RequestTokenVerifier; + + private string _RequestTokenCallback; + + private string _ConsumerVersion; + private EntityRef<OAuthConsumer> _OAuthConsumer; private EntityRef<User> _User; @@ -655,6 +733,12 @@ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChange partial void OnUserIdChanged(); partial void OnScopeChanging(string value); partial void OnScopeChanged(); + partial void OnRequestTokenVerifierChanging(string value); + partial void OnRequestTokenVerifierChanged(); + partial void OnRequestTokenCallbackChanging(string value); + partial void OnRequestTokenCallbackChanged(); + partial void OnConsumerVersionChanging(string value); + partial void OnConsumerVersionChanged(); #endregion public OAuthToken() @@ -724,7 +808,7 @@ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChange } } - [Column(Storage="_State", DbType="Int NOT NULL", CanBeNull=false)] + [Column(Storage="_State", DbType="INT NOT NULL", CanBeNull=false)] public TokenAuthorizationState State { get @@ -832,6 +916,66 @@ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChange } } + [Column(Storage="_RequestTokenVerifier")] + public string RequestTokenVerifier + { + get + { + return this._RequestTokenVerifier; + } + set + { + if ((this._RequestTokenVerifier != value)) + { + this.OnRequestTokenVerifierChanging(value); + this.SendPropertyChanging(); + this._RequestTokenVerifier = value; + this.SendPropertyChanged("RequestTokenVerifier"); + this.OnRequestTokenVerifierChanged(); + } + } + } + + [Column(Storage="_RequestTokenCallback")] + public string RequestTokenCallback + { + get + { + return this._RequestTokenCallback; + } + set + { + if ((this._RequestTokenCallback != value)) + { + this.OnRequestTokenCallbackChanging(value); + this.SendPropertyChanging(); + this._RequestTokenCallback = value; + this.SendPropertyChanged("RequestTokenCallback"); + this.OnRequestTokenCallbackChanged(); + } + } + } + + [Column(Storage="_ConsumerVersion")] + public string ConsumerVersion + { + get + { + return this._ConsumerVersion; + } + set + { + if ((this._ConsumerVersion != value)) + { + this.OnConsumerVersionChanging(value); + this.SendPropertyChanging(); + this._ConsumerVersion = value; + this.SendPropertyChanged("ConsumerVersion"); + this.OnConsumerVersionChanged(); + } + } + } + [Association(Name="OAuthConsumer_OAuthToken", Storage="_OAuthConsumer", ThisKey="ConsumerId", OtherKey="ConsumerId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")] public OAuthConsumer OAuthConsumer { diff --git a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs index 275a7c9..8ca4539 100644 --- a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs +++ b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs @@ -14,14 +14,22 @@ using DotNetOpenAuth.OAuth.Messages; public class DatabaseTokenManager : IServiceProviderTokenManager { #region IServiceProviderTokenManager - public string GetConsumerSecret(string consumerKey) { + public IConsumerDescription GetConsumer(string consumerKey) { var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault( consumerCandidate => consumerCandidate.ConsumerKey == consumerKey); if (consumerRow == null) { - throw new ArgumentException(); + throw new KeyNotFoundException(); } - return consumerRow.ConsumerSecret; + return consumerRow; + } + + public IServiceProviderRequestToken GetRequestToken(string token) { + try { + return Global.DataContext.OAuthTokens.First(t => t.Token == token); + } catch (InvalidOperationException ex) { + throw new KeyNotFoundException("Unrecognized token", ex); + } } #endregion @@ -51,6 +59,7 @@ public class DatabaseTokenManager : IServiceProviderTokenManager { }; Global.DataContext.OAuthTokens.InsertOnSubmit(newToken); + Global.DataContext.SubmitChanges(); } /// <summary> diff --git a/samples/OAuthServiceProvider/App_Code/OAuthConsumer.cs b/samples/OAuthServiceProvider/App_Code/OAuthConsumer.cs new file mode 100644 index 0000000..1255717 --- /dev/null +++ b/samples/OAuthServiceProvider/App_Code/OAuthConsumer.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------- +// <copyright file="OAuthConsumer.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using DotNetOpenAuth.OAuth.ChannelElements; + +public partial class OAuthConsumer : IConsumerDescription { + #region IConsumerDescription Members + + string IConsumerDescription.Key { + get { return this.ConsumerKey; } + } + + string IConsumerDescription.Secret { + get { return this.ConsumerSecret; } + } + + System.Security.Cryptography.X509Certificates.X509Certificate2 IConsumerDescription.Certificate { + get { return null; } + } + + Uri IConsumerDescription.Callback { + get { return this.Callback != null ? new Uri(this.Callback) : null; } + } + + DotNetOpenAuth.OAuth.VerificationCodeFormat IConsumerDescription.VerificationCodeFormat { + get { return this.VerificationCodeFormat; } + } + + int IConsumerDescription.VerificationCodeLength { + get { return this.VerificationCodeLength; } + } + + #endregion +} diff --git a/samples/OAuthServiceProvider/App_Code/OAuthToken.cs b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs new file mode 100644 index 0000000..445e88c --- /dev/null +++ b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="OAuthToken.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using DotNetOpenAuth.OAuth.ChannelElements; + +public partial class OAuthToken : IServiceProviderRequestToken { + #region IServiceProviderRequestToken Members + + string IServiceProviderRequestToken.Token { + get { return this.Token; } + } + + string IServiceProviderRequestToken.ConsumerKey { + get { return this.OAuthConsumer.ConsumerKey; } + } + + Uri IServiceProviderRequestToken.Callback { + get { return new Uri(this.RequestTokenCallback); } + set { this.RequestTokenCallback = value.AbsoluteUri; } + } + + string IServiceProviderRequestToken.VerificationCode { + get { return this.RequestTokenVerifier; } + set { this.RequestTokenVerifier = value; } + } + + Version IServiceProviderRequestToken.ConsumerVersion { + get { return new Version(this.ConsumerVersion); } + set { this.ConsumerVersion = value.ToString(); } + } + + #endregion +} diff --git a/samples/OAuthServiceProvider/App_Code/RequestScopedTokenMessage.cs b/samples/OAuthServiceProvider/App_Code/RequestScopedTokenMessage.cs index b33a734..4cc4860 100644 --- a/samples/OAuthServiceProvider/App_Code/RequestScopedTokenMessage.cs +++ b/samples/OAuthServiceProvider/App_Code/RequestScopedTokenMessage.cs @@ -1,4 +1,5 @@ -using DotNetOpenAuth.Messaging; +using System; +using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.Messages; /// <summary> @@ -9,7 +10,8 @@ public class RequestScopedTokenMessage : UnauthorizedTokenRequest { /// Initializes a new instance of the <see cref="RequestScopedTokenMessage"/> class. /// </summary> /// <param name="endpoint">The endpoint that will receive the message.</param> - public RequestScopedTokenMessage(MessageReceivingEndpoint endpoint) : base(endpoint) { + /// <param name="version">The OAuth version.</param> + public RequestScopedTokenMessage(MessageReceivingEndpoint endpoint, Version version) : base(endpoint, version) { } /// <summary> diff --git a/samples/OAuthServiceProvider/Members/Authorize.aspx b/samples/OAuthServiceProvider/Members/Authorize.aspx index 69f9498..2f5edf1 100644 --- a/samples/OAuthServiceProvider/Members/Authorize.aspx +++ b/samples/OAuthServiceProvider/Members/Authorize.aspx @@ -8,23 +8,31 @@ <b>Warning</b>: Never give your login credentials to another web site or application. </div> <asp:HiddenField runat="server" ID="OAuthAuthorizationSecToken" EnableViewState="false" /> - <p>The client web site or application - <asp:Label ID="consumerLabel" Font-Bold="true" runat="server" Text="[consumer]" /> - wants access to your - <asp:Label ID="desiredAccessLabel" Font-Bold="true" runat="server" Text="[protected resource]" />. - </p> + <p>The client web site or application <asp:Label ID="consumerLabel" Font-Bold="true" + runat="server" Text="[consumer]" /> wants access to your <asp:Label ID="desiredAccessLabel" + Font-Bold="true" runat="server" Text="[protected resource]" />. </p> <p>Do you want to allow this? </p> <div> <asp:Button ID="allowAccessButton" runat="server" Text="Yes" OnClick="allowAccessButton_Click" /> - <asp:Button ID="denyAccessButton" runat="server" Text="No" - onclick="denyAccessButton_Click" /> + <asp:Button ID="denyAccessButton" runat="server" Text="No" OnClick="denyAccessButton_Click" /> </div> <p>If you grant access now, you can revoke it at any time by returning to this page. </p> + <asp:Panel runat="server" BackColor="Red" ForeColor="White" Font-Bold="true" Visible="false" ID="OAuth10ConsumerWarning"> + This website is registered with service_PROVIDER_DOMAIN_NAME to make authorization requests, but has not been configured to send requests securely. If you grant access but you did not initiate this request at consumer_DOMAIN_NAME, it may be possible for other users of consumer_DOMAIN_NAME to access your data. We recommend you deny access unless you are certain that you initiated this request directly with consumer_DOMAIN_NAME. + </asp:Panel> </asp:View> <asp:View runat="server"> - <p>Authorization has been granted. Please inform the consumer application or web site - of this. </p> + <p>Authorization has been granted.</p> + <asp:MultiView runat="server" ID="verifierMultiView" ActiveViewIndex="0"> + <asp:View runat="server"> + <p>You must enter this verification code at the Consumer: <asp:Label runat="server" + ID="verificationCodeLabel" /> </p> + </asp:View> + <asp:View ID="View1" runat="server"> + <p>You may now close this window and return to the Consumer. </p> + </asp:View> + </asp:MultiView> </asp:View> <asp:View runat="server"> <p>Authorization has been denied. You're free to do whatever now. </p> diff --git a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs index b3094c9..f936c60 100644 --- a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs +++ b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs @@ -37,6 +37,8 @@ public partial class Authorize : System.Web.UI.Page { CryptoRandomDataGenerator.GetBytes(randomData); this.AuthorizationSecret = Convert.ToBase64String(randomData); OAuthAuthorizationSecToken.Value = this.AuthorizationSecret; + + OAuth10ConsumerWarning.Visible = Global.PendingOAuthAuthorization.IsUnsafeRequest; } } } @@ -54,6 +56,15 @@ public partial class Authorize : System.Web.UI.Page { var response = sp.PrepareAuthorizationResponse(pending); if (response != null) { sp.Channel.Send(response); + } else { + if (pending.IsUnsafeRequest) { + verifierMultiView.ActiveViewIndex = 1; + } else { + string verifier = ServiceProvider.CreateVerificationCode(VerificationCodeFormat.AlphaNumericNoLookAlikes, 10); + verificationCodeLabel.Text = verifier; + ITokenContainingMessage requestTokenMessage = pending; + Global.TokenManager.GetRequestToken(requestTokenMessage.Token).VerificationCode = verifier; + } } } |