summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj1
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/InMemoryTokenManager.cs23
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/YubikeyRelyingParty.cs207
-rw-r--r--samples/OpenIdOfflineProvider/MainWindow.xaml11
-rw-r--r--samples/OpenIdOfflineProvider/MainWindow.xaml.cs20
-rw-r--r--samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj12
-rw-r--r--samples/OpenIdProviderMvc/Web.config4
-rw-r--r--samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj4
-rw-r--r--samples/OpenIdProviderWebForms/Web.config5
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.cs7
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx10
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx.cs28
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx.designer.cs39
-rw-r--r--samples/OpenIdRelyingPartyMvc/OpenIdRelyingPartyMvc.csproj12
-rw-r--r--samples/OpenIdRelyingPartyMvc/Web.config4
15 files changed, 359 insertions, 28 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
index eab27db..41aff68 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
+++ b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
@@ -88,6 +88,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TwitterConsumer.cs" />
<Compile Include="Util.cs" />
+ <Compile Include="YubikeyRelyingParty.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetOpenAuth\DotNetOpenAuth.csproj">
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/InMemoryTokenManager.cs b/samples/DotNetOpenAuth.ApplicationBlock/InMemoryTokenManager.cs
index e83817a..8b769de 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/InMemoryTokenManager.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/InMemoryTokenManager.cs
@@ -10,6 +10,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
using System.Diagnostics;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OpenId.Extensions.OAuth;
/// <summary>
/// A token manager that only retains tokens in memory.
@@ -20,7 +21,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// where the user only signs in without providing any authorization to access
/// Twitter APIs except to authenticate, since that access token is only useful once.
/// </remarks>
- public class InMemoryTokenManager : IConsumerTokenManager {
+ public class InMemoryTokenManager : IConsumerTokenManager, IOpenIdOAuthTokenManager {
private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>();
/// <summary>
@@ -118,5 +119,25 @@ namespace DotNetOpenAuth.ApplicationBlock {
}
#endregion
+
+ #region IOpenIdOAuthTokenManager Members
+
+ /// <summary>
+ /// Stores a new request token obtained over an OpenID request.
+ /// </summary>
+ /// <param name="consumerKey">The consumer key.</param>
+ /// <param name="authorization">The authorization message carrying the request token and authorized access scope.</param>
+ /// <remarks>
+ /// <para>The token secret is the empty string.</para>
+ /// <para>Tokens stored by this method should be short-lived to mitigate
+ /// possible security threats. Their lifetime should be sufficient for the
+ /// relying party to receive the positive authentication assertion and immediately
+ /// send a follow-up request for the access token.</para>
+ /// </remarks>
+ public void StoreOpenIdAuthorizedRequestToken(string consumerKey, AuthorizationApprovedResponse authorization) {
+ this.tokensAndSecrets[authorization.RequestToken] = String.Empty;
+ }
+
+ #endregion
}
} \ No newline at end of file
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/YubikeyRelyingParty.cs b/samples/DotNetOpenAuth.ApplicationBlock/YubikeyRelyingParty.cs
new file mode 100644
index 0000000..6be749e
--- /dev/null
+++ b/samples/DotNetOpenAuth.ApplicationBlock/YubikeyRelyingParty.cs
@@ -0,0 +1,207 @@
+//-----------------------------------------------------------------------
+// <copyright file="YubikeyRelyingParty.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ApplicationBlock {
+ using System;
+ using System.Collections.Specialized;
+ using System.Globalization;
+ using System.IO;
+ using System.Net;
+ using System.Text;
+ using System.Text.RegularExpressions;
+
+ /// <summary>
+ /// The set of possible results from verifying a Yubikey token.
+ /// </summary>
+ public enum YubikeyResult {
+ /// <summary>
+ /// The OTP is valid.
+ /// </summary>
+ Ok,
+
+ /// <summary>
+ /// The OTP is invalid format.
+ /// </summary>
+ BadOtp,
+
+ /// <summary>
+ /// The OTP has already been seen by the service.
+ /// </summary>
+ ReplayedOtp,
+
+ /// <summary>
+ /// The HMAC signature verification failed.
+ /// </summary>
+ /// <remarks>
+ /// This indicates a bug in the relying party code.
+ /// </remarks>
+ BadSignature,
+
+ /// <summary>
+ /// The request lacks a parameter.
+ /// </summary>
+ /// <remarks>
+ /// This indicates a bug in the relying party code.
+ /// </remarks>
+ MissingParameter,
+
+ /// <summary>
+ /// The request id does not exist.
+ /// </summary>
+ NoSuchClient,
+
+ /// <summary>
+ /// The request id is not allowed to verify OTPs.
+ /// </summary>
+ OperationNotAllowed,
+
+ /// <summary>
+ /// Unexpected error in our server. Please contact Yubico if you see this error.
+ /// </summary>
+ BackendError,
+ }
+
+ /// <summary>
+ /// Provides verification of a Yubikey one-time password (OTP) as a means of authenticating
+ /// a user at your web site or application.
+ /// </summary>
+ /// <remarks>
+ /// Please visit http://yubico.com/ for more information about this authentication method.
+ /// </remarks>
+ public class YubikeyRelyingParty {
+ /// <summary>
+ /// The default Yubico authorization server to use for validation and replay protection.
+ /// </summary>
+ private const string DefaultYubicoAuthorizationServer = "https://api.yubico.com/wsapi/verify";
+
+ /// <summary>
+ /// The format of the lines in the Yubico server response.
+ /// </summary>
+ private static readonly Regex ResultLineMatcher = new Regex(@"^(?<key>[^=]+)=(?<value>.*)$");
+
+ /// <summary>
+ /// The Yubico authorization server to use for validation and replay protection.
+ /// </summary>
+ private readonly string yubicoAuthorizationServer;
+
+ /// <summary>
+ /// The authorization ID assigned to your individual site by Yubico.
+ /// </summary>
+ private readonly int yubicoAuthorizationId;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="YubikeyRelyingParty"/> class
+ /// that uses the default Yubico server for validation and replay protection.
+ /// </summary>
+ /// <param name="authorizationId">The authorization ID assigned to your individual site by Yubico.
+ /// Get one from https://upgrade.yubico.com/getapikey/</param>
+ public YubikeyRelyingParty(int authorizationId)
+ : this(authorizationId, DefaultYubicoAuthorizationServer) {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="YubikeyRelyingParty"/> class.
+ /// </summary>
+ /// <param name="authorizationId">The authorization ID assigned to your individual site by Yubico.
+ /// Contact tech@yubico.com if you haven't got an authId for your site.</param>
+ /// <param name="yubicoAuthorizationServer">The Yubico authorization server to use for validation and replay protection.</param>
+ public YubikeyRelyingParty(int authorizationId, string yubicoAuthorizationServer) {
+ if (authorizationId < 0) {
+ throw new ArgumentOutOfRangeException("authorizationId");
+ }
+
+ if (!Uri.IsWellFormedUriString(yubicoAuthorizationServer, UriKind.Absolute)) {
+ throw new ArgumentException("Invalid authorization server URI", "yubicoAuthorizationServer");
+ }
+
+ if (!yubicoAuthorizationServer.StartsWith(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) {
+ throw new ArgumentException("HTTPS is required for the Yubico server. HMAC response verification not supported.", "yubicoAuthorizationServer");
+ }
+
+ this.yubicoAuthorizationId = authorizationId;
+ this.yubicoAuthorizationServer = yubicoAuthorizationServer;
+ }
+
+ /// <summary>
+ /// Extracts the username out of a Yubikey token.
+ /// </summary>
+ /// <param name="yubikeyToken">The yubikey token.</param>
+ /// <returns>A 12 character string that is unique for this particular Yubikey device.</returns>
+ public static string ExtractUsername(string yubikeyToken) {
+ EnsureWellFormedToken(yubikeyToken);
+ return yubikeyToken.Substring(0, 12);
+ }
+
+ /// <summary>
+ /// Determines whether the specified yubikey token is valid and has not yet been used.
+ /// </summary>
+ /// <param name="yubikeyToken">The yubikey token.</param>
+ /// <returns>
+ /// <c>true</c> if the specified yubikey token is valid; otherwise, <c>false</c>.
+ /// </returns>
+ /// <exception cref="WebException">Thrown when the validity of the token could not be confirmed due to network issues.</exception>
+ public YubikeyResult IsValid(string yubikeyToken) {
+ EnsureWellFormedToken(yubikeyToken);
+
+ StringBuilder authorizationUri = new StringBuilder(this.yubicoAuthorizationServer);
+ authorizationUri.Append("?id=");
+ authorizationUri.Append(Uri.EscapeDataString(this.yubicoAuthorizationId.ToString(CultureInfo.InvariantCulture)));
+ authorizationUri.Append("&otp=");
+ authorizationUri.Append(Uri.EscapeDataString(yubikeyToken));
+
+ var request = WebRequest.Create(authorizationUri.ToString());
+ using (var response = request.GetResponse()) {
+ using (var responseReader = new StreamReader(response.GetResponseStream())) {
+ string line;
+ var result = new NameValueCollection();
+ while ((line = responseReader.ReadLine()) != null) {
+ Match m = ResultLineMatcher.Match(line);
+ if (m.Success) {
+ result[m.Groups["key"].Value] = m.Groups["value"].Value;
+ }
+ }
+
+ return ParseResult(result["status"]);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Parses the Yubico server result.
+ /// </summary>
+ /// <param name="status">The status field from the response.</param>
+ /// <returns>The enum value representing the result.</returns>
+ private static YubikeyResult ParseResult(string status) {
+ switch (status) {
+ case "OK": return YubikeyResult.Ok;
+ case "BAD_OTP": return YubikeyResult.BadOtp;
+ case "REPLAYED_OTP": return YubikeyResult.ReplayedOtp;
+ case "BAD_SIGNATURE": return YubikeyResult.BadSignature;
+ case "MISSING_PARAMETER": return YubikeyResult.MissingParameter;
+ case "NO_SUCH_CLIENT": return YubikeyResult.NoSuchClient;
+ case "OPERATION_NOT_ALLOWED": return YubikeyResult.OperationNotAllowed;
+ case "BACKEND_ERROR": return YubikeyResult.BackendError;
+ default: throw new ArgumentOutOfRangeException("status", status, "Unexpected status value.");
+ }
+ }
+
+ /// <summary>
+ /// Ensures the OTP is well formed.
+ /// </summary>
+ /// <param name="yubikeyToken">The yubikey token.</param>
+ private static void EnsureWellFormedToken(string yubikeyToken) {
+ if (yubikeyToken == null) {
+ throw new ArgumentNullException("yubikeyToken");
+ }
+
+ yubikeyToken = yubikeyToken.Trim();
+
+ if (yubikeyToken.Length <= 12) {
+ throw new ArgumentException("Yubikey token has unexpected length.");
+ }
+ }
+ }
+}
diff --git a/samples/OpenIdOfflineProvider/MainWindow.xaml b/samples/OpenIdOfflineProvider/MainWindow.xaml
index de215ba..5e9438f 100644
--- a/samples/OpenIdOfflineProvider/MainWindow.xaml
+++ b/samples/OpenIdOfflineProvider/MainWindow.xaml
@@ -6,7 +6,9 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
+ <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
@@ -20,6 +22,13 @@
<ComboBoxItem>Auto respond: No</ComboBoxItem>
<ComboBoxItem>Intercept</ComboBoxItem>
</ComboBox>
- <TextBox Height="auto" Margin="0,8,0,0" Grid.Row="2" Grid.ColumnSpan="2" Name="logBox" IsReadOnly="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" />
+ <Expander Grid.Row="2" Grid.ColumnSpan="2" Header="Advanced options">
+ <StackPanel Margin="3">
+ <CheckBox Name="directedIdentityTrailingPeriodsCheckbox">Directed identity uses trailing periods in path</CheckBox>
+ <CheckBox Name="capitalizedHostName">Directed identity uses capitalized host name in claimed identifier</CheckBox>
+ </StackPanel>
+ </Expander>
+ <TextBox Height="auto" Margin="0,8,0,0" Grid.Row="3" Grid.ColumnSpan="2" Name="logBox" IsReadOnly="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" />
+ <Button Grid.Row="4" Grid.ColumnSpan="2" Name="clearLogButton" Click="ClearLogButton_Click">Clear log</Button>
</Grid>
</Window>
diff --git a/samples/OpenIdOfflineProvider/MainWindow.xaml.cs b/samples/OpenIdOfflineProvider/MainWindow.xaml.cs
index 8f04da3..0fcac9c 100644
--- a/samples/OpenIdOfflineProvider/MainWindow.xaml.cs
+++ b/samples/OpenIdOfflineProvider/MainWindow.xaml.cs
@@ -25,6 +25,7 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider {
using System.Windows.Navigation;
using System.Windows.Shapes;
using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Provider;
using log4net;
using log4net.Appender;
@@ -117,7 +118,15 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider {
switch (checkidRequestList.SelectedIndex) {
case 0:
if (authRequest.IsDirectedIdentity) {
- authRequest.ClaimedIdentifier = new Uri(this.hostedProvider.UserIdentityPageBase, "directedidentity");
+ string userIdentityPageBase = this.hostedProvider.UserIdentityPageBase.AbsoluteUri;
+ if (capitalizedHostName.IsChecked.Value) {
+ userIdentityPageBase = (this.hostedProvider.UserIdentityPageBase.Scheme + Uri.SchemeDelimiter + this.hostedProvider.UserIdentityPageBase.Authority).ToUpperInvariant() + this.hostedProvider.UserIdentityPageBase.PathAndQuery;
+ }
+ string leafPath = "directedidentity";
+ if (directedIdentityTrailingPeriodsCheckbox.IsChecked.Value) {
+ leafPath += ".";
+ }
+ authRequest.ClaimedIdentifier = Identifier.Parse(userIdentityPageBase + leafPath, true);
authRequest.LocalIdentifier = authRequest.ClaimedIdentifier;
}
authRequest.IsAuthenticated = true;
@@ -169,5 +178,14 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider {
MessageBox.Show(this, ex.Message, "Error while copying OP Identifier to the clipboard", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
+
+ /// <summary>
+ /// Handles the Click event of the ClearLogButton control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+ private void ClearLogButton_Click(object sender, RoutedEventArgs e) {
+ logBox.Clear();
+ }
}
}
diff --git a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
index a7a2296..72b6c14 100644
--- a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
+++ b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
@@ -44,19 +44,13 @@
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
- <Reference Include="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
- <HintPath>..\..\lib\System.Web.Mvc.dll</HintPath>
- </Reference>
+ <Reference Include="System.Web.Mvc" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
- <Reference Include="System.Web.Abstractions">
- <HintPath>..\..\lib\System.Web.Abstractions.dll</HintPath>
- </Reference>
- <Reference Include="System.Web.Routing">
- <HintPath>..\..\lib\System.Web.Routing.dll</HintPath>
- </Reference>
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
diff --git a/samples/OpenIdProviderMvc/Web.config b/samples/OpenIdProviderMvc/Web.config
index 8f145b0..f8d2389 100644
--- a/samples/OpenIdProviderMvc/Web.config
+++ b/samples/OpenIdProviderMvc/Web.config
@@ -194,12 +194,12 @@
<runtime>
<legacyHMACWarning enabled="0" />
- <!-- If you target ASP.NET MVC 2, uncomment this so that MVC 1 components such as DotNetOpenAuth will work with it.
+ <!-- If you target ASP.NET MVC 2, uncomment this so that MVC 1 components such as DotNetOpenAuth will work with it. -->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
- </assemblyBinding>-->
+ </assemblyBinding>
</runtime>
</configuration>
diff --git a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
index 603b372..4cd84c1 100644
--- a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
+++ b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
@@ -183,6 +183,10 @@
<Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project>
<Name>DotNetOpenAuth</Name>
</ProjectReference>
+ <ProjectReference Include="..\DotNetOpenAuth.ApplicationBlock\DotNetOpenAuth.ApplicationBlock.csproj">
+ <Project>{AA78D112-D889-414B-A7D4-467B34C7B663}</Project>
+ <Name>DotNetOpenAuth.ApplicationBlock</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config
index b76231b..de92621 100644
--- a/samples/OpenIdProviderWebForms/Web.config
+++ b/samples/OpenIdProviderWebForms/Web.config
@@ -62,6 +62,11 @@
<reporting enabled="true" />
</dotNetOpenAuth>
+ <appSettings>
+ <!-- Get your own Yubico API key here: https://upgrade.yubico.com/getapikey/ -->
+ <add key="YubicoAPIKey" value="3961"/>
+ </appSettings>
+
<system.web>
<!--
Set compilation debug="true" to insert debugging
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs
index b392d85..40c17c0 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.cs
@@ -50,7 +50,12 @@ namespace OpenIdProviderWebForms {
this.profileFields.SetRequiredFieldsFromRequest(requestedFields);
if (!IsPostBack) {
var sregResponse = requestedFields.CreateResponse();
- sregResponse.Email = Membership.GetUser().Email;
+
+ // We MAY not have an entry for this user if they used Yubikey to log in.
+ MembershipUser user = Membership.GetUser();
+ if (user != null) {
+ sregResponse.Email = Membership.GetUser().Email;
+ }
this.profileFields.SetOpenIdProfileFields(sregResponse);
}
}
diff --git a/samples/OpenIdProviderWebForms/login.aspx b/samples/OpenIdProviderWebForms/login.aspx
index e8f42c5..f7898cc 100644
--- a/samples/OpenIdProviderWebForms/login.aspx
+++ b/samples/OpenIdProviderWebForms/login.aspx
@@ -14,4 +14,14 @@
<tr><td>bob3</td><td>test</td></tr>
<tr><td>bob4</td><td>test</td></tr>
</table>
+
+ <asp:Panel DefaultButton="yubicoButton" runat="server" style="margin-top: 25px" ID="yubicoPanel">
+ Login with Yubikey:
+ <asp:TextBox runat="server" type="text" ID="yubicoBox" ToolTip="Click here and press your Yubikey button."
+ style="background-image: url(http://yubico.com/favicon.ico); background-repeat: no-repeat; background-position: 0px 1px; padding-left: 18px; width: 20em;"
+ MaxLength="44" AutoCompleteType="Disabled" />
+ <asp:Button runat="server" ID="yubicoButton" Text="Login"
+ onclick="yubicoButton_Click" />
+ <asp:Label Text="[Yubikey Result]" runat="server" EnableViewState="false" Visible="false" ForeColor="Red" ID="yubikeyFailureLabel" />
+ </asp:Panel>
</asp:Content> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/login.aspx.cs b/samples/OpenIdProviderWebForms/login.aspx.cs
index 4051877..ef5b2c4 100644
--- a/samples/OpenIdProviderWebForms/login.aspx.cs
+++ b/samples/OpenIdProviderWebForms/login.aspx.cs
@@ -1,6 +1,10 @@
namespace OpenIdProviderWebForms {
using System;
+ using System.Configuration;
+ using System.Globalization;
+ using System.Web.Security;
using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
using DotNetOpenAuth.OpenId.Provider;
/// <summary>
@@ -9,6 +13,8 @@ namespace OpenIdProviderWebForms {
public partial class login : System.Web.UI.Page {
protected void Page_Load(object src, EventArgs e) {
if (!IsPostBack) {
+ this.yubicoPanel.Visible = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["YubicoAPIKey"]);
+
if (ProviderEndpoint.PendingAuthenticationRequest != null &&
!ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) {
this.login1.UserName = Code.Util.ExtractUserName(
@@ -18,5 +24,27 @@ namespace OpenIdProviderWebForms {
}
}
}
+
+ protected void yubicoButton_Click(object sender, EventArgs e) {
+ string username;
+ if (this.TryVerifyYubikeyAndGetUsername(this.yubicoBox.Text, out username)) {
+ FormsAuthentication.RedirectFromLoginPage(username, false);
+ }
+ }
+
+ private bool TryVerifyYubikeyAndGetUsername(string token, out string username) {
+ var yubikey = new YubikeyRelyingParty(int.Parse(ConfigurationManager.AppSettings["YubicoAPIKey"], CultureInfo.InvariantCulture));
+ YubikeyResult result = yubikey.IsValid(token);
+ switch (result) {
+ case YubikeyResult.Ok:
+ username = YubikeyRelyingParty.ExtractUsername(token);
+ return true;
+ default:
+ this.yubikeyFailureLabel.Visible = true;
+ this.yubikeyFailureLabel.Text = result.ToString();
+ username = null;
+ return false;
+ }
+ }
}
} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/login.aspx.designer.cs b/samples/OpenIdProviderWebForms/login.aspx.designer.cs
index 83826a1..307dd96 100644
--- a/samples/OpenIdProviderWebForms/login.aspx.designer.cs
+++ b/samples/OpenIdProviderWebForms/login.aspx.designer.cs
@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:2.0.50727.3521
//
// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
+// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
@@ -21,5 +20,41 @@ namespace OpenIdProviderWebForms {
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Login login1;
+
+ /// <summary>
+ /// yubicoPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel yubicoPanel;
+
+ /// <summary>
+ /// yubicoBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox yubicoBox;
+
+ /// <summary>
+ /// yubicoButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button yubicoButton;
+
+ /// <summary>
+ /// yubikeyFailureLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label yubikeyFailureLabel;
}
}
diff --git a/samples/OpenIdRelyingPartyMvc/OpenIdRelyingPartyMvc.csproj b/samples/OpenIdRelyingPartyMvc/OpenIdRelyingPartyMvc.csproj
index a94bd88..a3c7b78 100644
--- a/samples/OpenIdRelyingPartyMvc/OpenIdRelyingPartyMvc.csproj
+++ b/samples/OpenIdRelyingPartyMvc/OpenIdRelyingPartyMvc.csproj
@@ -43,19 +43,13 @@
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
- <Reference Include="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
- <HintPath>..\..\lib\System.Web.Mvc.dll</HintPath>
- </Reference>
+ <Reference Include="System.Web.Mvc" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
- <Reference Include="System.Web.Abstractions">
- <HintPath>..\..\lib\System.Web.Abstractions.dll</HintPath>
- </Reference>
- <Reference Include="System.Web.Routing">
- <HintPath>..\..\lib\System.Web.Routing.dll</HintPath>
- </Reference>
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
diff --git a/samples/OpenIdRelyingPartyMvc/Web.config b/samples/OpenIdRelyingPartyMvc/Web.config
index 6aba949..0585cf5 100644
--- a/samples/OpenIdRelyingPartyMvc/Web.config
+++ b/samples/OpenIdRelyingPartyMvc/Web.config
@@ -171,12 +171,12 @@
<runtime>
<legacyHMACWarning enabled="0" />
- <!-- If you target ASP.NET MVC 2, uncomment this so that MVC 1 components such as DotNetOpenAuth will work with it.
+ <!-- If you target ASP.NET MVC 2, uncomment this so that MVC 1 components such as DotNetOpenAuth will work with it. -->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
- </assemblyBinding>-->
+ </assemblyBinding>
</runtime>
</configuration>