diff options
Diffstat (limited to 'samples')
-rw-r--r-- | samples/OpenIdOfflineProvider/App.config | 10 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/CheckIdWindow.xaml | 84 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/CheckIdWindow.xaml.cs | 91 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/HostedProvider.cs | 127 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/MainWindow.xaml | 27 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/MainWindow.xaml.cs | 83 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/NativeMethods.cs | 36 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj | 17 | ||||
-rw-r--r-- | samples/OpenIdOfflineProvider/openid.ico | bin | 0 -> 17006 bytes |
9 files changed, 400 insertions, 75 deletions
diff --git a/samples/OpenIdOfflineProvider/App.config b/samples/OpenIdOfflineProvider/App.config index 93e2027..cd04b13 100644 --- a/samples/OpenIdOfflineProvider/App.config +++ b/samples/OpenIdOfflineProvider/App.config @@ -4,6 +4,16 @@ <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth" requirePermission="false" allowLocation="true"/> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/> </configSections> + <dotNetOpenAuth> + <messaging> + <untrustedWebRequest> + <whitelistHosts> + <!-- since this is a tool designed for local use and will often be used with localhost --> + <add name="localhost" /> + </whitelistHosts> + </untrustedWebRequest> + </messaging> + </dotNetOpenAuth> <log4net> <appender name="TextBoxAppender" type="log4net.Appender.TextWriterAppender"> <immediateFlush value="true" /> diff --git a/samples/OpenIdOfflineProvider/CheckIdWindow.xaml b/samples/OpenIdOfflineProvider/CheckIdWindow.xaml new file mode 100644 index 0000000..29e5126 --- /dev/null +++ b/samples/OpenIdOfflineProvider/CheckIdWindow.xaml @@ -0,0 +1,84 @@ +<Window x:Class="DotNetOpenAuth.OpenIdOfflineProvider.CheckIdWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + Title="Authentication request" Height="345" Width="379" ShowInTaskbar="False"> + <DockPanel Margin="12"> + <TextBlock DockPanel.Dock="Top" TextWrapping="Wrap">An authentication request has been received. How do you want to proceed?</TextBlock> + <Expander DockPanel.Dock="Top" Header="View request details" IsExpanded="True"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto" /> + <ColumnDefinition /> + </Grid.ColumnDefinitions> + <Label>Immediate?</Label> + <Label Grid.Column="1" Name="immediateModeLabel" Content="Yes" /> + <Label Grid.Column="1" Name="setupModeLabel" Content="No" /> + <Label Grid.Row="1">Realm</Label> + <Label Grid.Row="1" Grid.Column="1" Name="realmLabel" /> + <!--<Label Grid.Row="2">Callback</Label> + <Label Grid.Row="2" Grid.Column="1" Name="callbackLabel" />--> + <Label Grid.Row="3">Discoverable</Label> + <Label Grid.Row="3" Grid.Column="1" Name="discoverableYesLabel" Content="Yes" /> + <Label Grid.Row="3" Grid.Column="1" Name="discoverableNoLabel" Content="No" /> + <!--<Label Grid.Row="4">Shared association?</Label> + <Label Grid.Row="4" Grid.Column="1" Name="sharedAssociationLabel" Content="Yes" /> + <Label Grid.Row="4" Grid.Column="1" Name="privateAssociationLabel" Content="No" />--> + </Grid> + </Expander> + <StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" Margin="0,12,0,0"> + <Button Name="sendResponseButton" IsDefault="True" Margin="0,0,4,0" Click="sendResponseButton_Click">Send response</Button> + <Button Name="cancelButton" IsCancel="True">Cancel</Button> + </StackPanel> + + <TabControl Name="tabControl1"> + <TabItem Header="Positive assertion" Name="positiveTab"> + <StackPanel> + <TextBlock TextWrapping="Wrap">You may customize the positive assertion if you wish.</TextBlock> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + <RowDefinition Height="auto" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto" /> + <ColumnDefinition Width="*" /> + </Grid.ColumnDefinitions> + <Label>Claimed identifier</Label> + <TextBox Grid.Column="1" Name="claimedIdentifierBox" /> + <Label Grid.Row="1">OP Local identifier</Label> + <TextBox Grid.Column="1" Grid.Row="1" Name="localIdentifierBox" /> + <!--<Label Grid.Row="2">Association</Label> + <WrapPanel Grid.Row="2" Grid.Column="1" VerticalAlignment="Center"> + <RadioButton Margin="0,0,12,0" GroupName="AssociationType">Shared</RadioButton> + <RadioButton GroupName="AssociationType">Private</RadioButton> + </WrapPanel>--> + </Grid> + </StackPanel> + </TabItem> + <TabItem Header="Negative assertion" Name="negativeTab"> + <TextBlock TextWrapping="Wrap">There is nothing to customize in a negative assertion.</TextBlock> + </TabItem> + <!--<TabItem Header="Error" Name="errorTab" > + <StackPanel> + <TextBlock TextWrapping="Wrap">What message do you want to send describing the simulated error?</TextBlock> + <TextBox TextWrapping="Wrap" /> + </StackPanel> + </TabItem> + <TabItem Header="Invalid" Name="invalidTab"> + <StackPanel> + <TextBlock TextWrapping="Wrap">This tab is useful for testing a relying party's resiliance to invalid responses.</TextBlock> + <TextBlock TextWrapping="Wrap">But it's not implemented yet. :)</TextBlock> + </StackPanel> + </TabItem>--> + </TabControl> + </DockPanel> +</Window> diff --git a/samples/OpenIdOfflineProvider/CheckIdWindow.xaml.cs b/samples/OpenIdOfflineProvider/CheckIdWindow.xaml.cs new file mode 100644 index 0000000..597f72f --- /dev/null +++ b/samples/OpenIdOfflineProvider/CheckIdWindow.xaml.cs @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------- +// <copyright file="CheckIdWindow.xaml.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenIdOfflineProvider { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Text; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Data; + using System.Windows.Documents; + using System.Windows.Input; + using System.Windows.Media; + using System.Windows.Media.Imaging; + using System.Windows.Shapes; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Provider; + + /// <summary> + /// Interaction logic for CheckIdWindow.xaml + /// </summary> + public partial class CheckIdWindow : Window { + /// <summary> + /// Initializes a new instance of the <see cref="CheckIdWindow"/> class. + /// </summary> + /// <param name="provider">The OpenID Provider host.</param> + /// <param name="request">The incoming authentication request.</param> + private CheckIdWindow(HostedProvider provider, IAuthenticationRequest request) { + Contract.Requires(request != null); + + InitializeComponent(); + + // Initialize the window with appropriate values. + this.realmLabel.Content = request.Realm; + this.immediateModeLabel.Visibility = request.Immediate ? Visibility.Visible : Visibility.Collapsed; + this.setupModeLabel.Visibility = request.Immediate ? Visibility.Collapsed : Visibility.Visible; + + bool isRPDiscoverable = request.IsReturnUrlDiscoverable(provider.Provider.Channel.WebRequestHandler); + this.discoverableYesLabel.Visibility = isRPDiscoverable ? Visibility.Visible : Visibility.Collapsed; + this.discoverableNoLabel.Visibility = isRPDiscoverable ? Visibility.Collapsed : Visibility.Visible; + + if (request.IsDirectedIdentity) { + this.claimedIdentifierBox.Text = provider.UserIdentityPageBase.AbsoluteUri; + this.localIdentifierBox.Text = provider.UserIdentityPageBase.AbsoluteUri; + } else { + this.claimedIdentifierBox.Text = request.ClaimedIdentifier; + this.localIdentifierBox.Text = request.LocalIdentifier; + } + } + + /// <summary> + /// Processes an authentication request by a popup window. + /// </summary> + /// <param name="provider">The OpenID Provider host.</param> + /// <param name="request">The incoming authentication request.</param> + internal static void ProcessAuthentication(HostedProvider provider, IAuthenticationRequest request) { + Contract.Requires(provider != null); + Contract.Requires(request != null); + + var window = new CheckIdWindow(provider, request); + bool? result = window.ShowDialog(); + + // If the user pressed Esc or cancel, just send a negative assertion. + if (!result.HasValue || !result.Value) { + request.IsAuthenticated = false; + return; + } + + request.IsAuthenticated = window.tabControl1.SelectedItem == window.positiveTab; + if (request.IsAuthenticated.Value) { + request.ClaimedIdentifier = window.claimedIdentifierBox.Text; + request.LocalIdentifier = window.localIdentifierBox.Text; + } + } + + /// <summary> + /// Handles the Click event of the sendResponseButton 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 sendResponseButton_Click(object sender, RoutedEventArgs e) { + this.DialogResult = true; + Close(); + } + } +} diff --git a/samples/OpenIdOfflineProvider/HostedProvider.cs b/samples/OpenIdOfflineProvider/HostedProvider.cs index 7a8cf01..3d50dd9 100644 --- a/samples/OpenIdOfflineProvider/HostedProvider.cs +++ b/samples/OpenIdOfflineProvider/HostedProvider.cs @@ -9,9 +9,11 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; + using System.Linq; using System.Net; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Provider; + using log4net; /// <summary> /// The OpenID Provider host. @@ -25,17 +27,12 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { /// <summary> /// The path to the OP Identifier. /// </summary> - private const string OPIdentifier = "/"; + private const string OPIdentifierPath = "/"; /// <summary> - /// The path to the user identity page that always generates a positive assertion. + /// The URL path with which all user identities must start. /// </summary> - private const string YesIdentity = "/user"; - - /// <summary> - /// The path to the user identity page that always generates a negative response. - /// </summary> - private const string NoIdentity = "/no"; + private const string UserIdentifierPath = "/user/"; /// <summary> /// The <see cref="OpenIdProvider"/> instance that processes incoming requests. @@ -51,8 +48,6 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { /// Initializes a new instance of the <see cref="HostedProvider"/> class. /// </summary> internal HostedProvider() { - this.AffirmativeIdentities = new HashSet<Uri>(); - this.NegativeIdentitities = new HashSet<Uri>(); } /// <summary> @@ -66,14 +61,16 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { } /// <summary> - /// Gets a collection of identity URLs that always produce positive assertions. + /// Gets the <see cref="OpenIdProvider"/> instance that processes incoming requests. /// </summary> - internal ICollection<Uri> AffirmativeIdentities { get; private set; } + internal OpenIdProvider Provider { + get { return this.provider; } + } /// <summary> - /// Gets a collection of identity URLs that always produce cancellation responses. + /// Gets or sets the delegate that handles authentication requests. /// </summary> - internal ICollection<Uri> NegativeIdentitities { get; private set; } + internal Action<HttpRequestInfo, HttpListenerResponse> ProcessRequest { get; set; } /// <summary> /// Gets the provider endpoint. @@ -86,6 +83,26 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { } /// <summary> + /// Gets the base URI that all user identities must start with. + /// </summary> + internal Uri UserIdentityPageBase { + get { + Contract.Requires(this.IsRunning); + return new Uri(this.httpHost.BaseUri, UserIdentifierPath); + } + } + + /// <summary> + /// Gets the OP identifier. + /// </summary> + internal Uri OPIdentifier { + get { + Contract.Requires(this.IsRunning); + return new Uri(this.httpHost.BaseUri, OPIdentifierPath); + } + } + + /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { @@ -98,8 +115,6 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { internal void StartProvider() { Contract.Ensures(this.IsRunning); this.httpHost = HttpHost.CreateHost(this.RequestHandler); - this.AffirmativeIdentities.Add(new Uri(this.httpHost.BaseUri, YesIdentity)); - this.NegativeIdentitities.Add(new Uri(this.httpHost.BaseUri, NoIdentity)); } /// <summary> @@ -138,8 +153,8 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { /// <param name="providerEndpoint">The provider endpoint.</param> /// <param name="localId">The local id.</param> /// <returns>The HTML document to return to the RP.</returns> - private static string GenerateHtmlDiscoveryDocument(string providerEndpoint, string localId) { - Contract.Requires(providerEndpoint != null && providerEndpoint.Length > 0); + private static string GenerateHtmlDiscoveryDocument(Uri providerEndpoint, string localId) { + Contract.Requires(providerEndpoint != null); const string DelegatedHtmlDiscoveryFormat = @"<html><head> <link rel=""openid.server"" href=""{0}"" /> @@ -155,51 +170,79 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { return string.Format( localId != null ? DelegatedHtmlDiscoveryFormat : NonDelegatedHtmlDiscoveryFormat, - providerEndpoint, + providerEndpoint.AbsoluteUri, localId); } /// <summary> + /// Generates the OP Identifier XRDS document. + /// </summary> + /// <param name="providerEndpoint">The provider endpoint.</param> + /// <param name="supportedExtensions">The supported extensions.</param> + /// <returns>The content of the XRDS document.</returns> + private static string GenerateXrdsOPIdentifierDocument(Uri providerEndpoint, IEnumerable<string> supportedExtensions) { + Contract.Requires(providerEndpoint != null); + Contract.Requires(supportedExtensions != null); + + const string OPIdentifierDiscoveryFormat = @"<xrds:XRDS + xmlns:xrds='xri://$xrds' + xmlns:openid='http://openid.net/xmlns/1.0' + xmlns='xri://$xrd*($v*2.0)'> + <XRD> + <Service priority='10'> + <Type>http://specs.openid.net/auth/2.0/server</Type> + {1} + <URI>{0}</URI> + </Service> + </XRD> +</xrds:XRDS>"; + + string extensions = string.Join( + "\n\t\t\t", + supportedExtensions.Select(ext => "<Type>" + ext + "</Type>").ToArray()); + return string.Format( + OPIdentifierDiscoveryFormat, + providerEndpoint.AbsoluteUri, + extensions); + } + + /// <summary> /// Handles incoming HTTP requests. /// </summary> /// <param name="context">The HttpListener context.</param> private void RequestHandler(HttpListenerContext context) { Contract.Requires(context != null); Contract.Requires(context.Response.OutputStream != null); + Contract.Requires(this.ProcessRequest != null); Stream outputStream = context.Response.OutputStream; Contract.Assume(outputStream != null); // CC static verification shortcoming. + UriBuilder providerEndpointBuilder = new UriBuilder(); + providerEndpointBuilder.Scheme = Uri.UriSchemeHttp; + providerEndpointBuilder.Host = "localhost"; + providerEndpointBuilder.Port = context.Request.Url.Port; + providerEndpointBuilder.Path = ProviderPath; + Uri providerEndpoint = providerEndpointBuilder.Uri; + if (context.Request.Url.AbsolutePath == ProviderPath) { HttpRequestInfo requestInfo = new HttpRequestInfo(context.Request); - IRequest providerRequest = this.provider.GetRequest(requestInfo); - if (providerRequest == null) { - App.Logger.Error("A request came in that did not carry an OpenID message."); - context.Response.StatusCode = (int)HttpStatusCode.BadRequest; - using (StreamWriter sw = new StreamWriter(outputStream)) { - sw.WriteLine("<html><body>This is an OpenID Provider endpoint.</body></html>"); - } - return; - } - - if (!providerRequest.IsResponseReady) { - var authRequest = providerRequest as IAuthenticationRequest; - if (authRequest.IsDirectedIdentity) { - throw new NotImplementedException(); - } - - authRequest.IsAuthenticated = new Uri(authRequest.ClaimedIdentifier).AbsolutePath == YesIdentity; - } - - this.provider.PrepareResponse(providerRequest).Send(context.Response); - } else if (context.Request.Url.AbsolutePath == YesIdentity || context.Request.Url.AbsolutePath == NoIdentity) { + this.ProcessRequest(requestInfo, context.Response); + } else if (context.Request.Url.AbsolutePath.StartsWith(UserIdentifierPath, StringComparison.Ordinal)) { using (StreamWriter sw = new StreamWriter(outputStream)) { - string providerEndpoint = string.Format("http://localhost:{0}{1}", context.Request.Url.Port, ProviderPath); + context.Response.StatusCode = (int)HttpStatusCode.OK; + string localId = null; // string.Format("http://localhost:{0}/user", context.Request.Url.Port); string html = GenerateHtmlDiscoveryDocument(providerEndpoint, localId); sw.WriteLine(html); } - + context.Response.OutputStream.Close(); + } else if (context.Request.Url == this.OPIdentifier) { + context.Response.ContentType = "application/xrds+xml"; context.Response.StatusCode = (int)HttpStatusCode.OK; + App.Logger.Info("Discovery on OP Identifier detected."); + using (StreamWriter sw = new StreamWriter(outputStream)) { + sw.Write(GenerateXrdsOPIdentifierDocument(providerEndpoint, Enumerable.Empty<string>())); + } context.Response.OutputStream.Close(); } else { context.Response.StatusCode = (int)HttpStatusCode.NotFound; diff --git a/samples/OpenIdOfflineProvider/MainWindow.xaml b/samples/OpenIdOfflineProvider/MainWindow.xaml index 80a9fe4..de215ba 100644 --- a/samples/OpenIdOfflineProvider/MainWindow.xaml +++ b/samples/OpenIdOfflineProvider/MainWindow.xaml @@ -2,31 +2,24 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="DotNetOpenAuth Offline OpenID Provider" Height="289" Width="493"> - <Grid> + <Grid Margin="4"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> - <Label >Port</Label> - <Label Name="portLabel" Grid.Column="1" /> - <Label Grid.Row="1">OP Identifier</Label> - <Label Grid.Column="1" Grid.Row="1" Name="opIdentifierLabel"></Label> - <Label Grid.Row="2">Yes Identifier</Label> - <Label Grid.Column="1" Grid.Row="2" Name="yesIdentity" ></Label> - <Label Grid.Row="3">No Identifier</Label> - <Label Grid.Column="1" Grid.Row="3" Name="noIdentity" ></Label> - <StackPanel Orientation="Horizontal" Grid.Row="4" Grid.ColumnSpan="2"> - <Button Name="startButton" Click="startButton_Click" Padding="10,0,10,0">Start</Button> - <Button Name="stopButton" Click="stopButton_Click" Padding="10,0,10,0">Stop</Button> - </StackPanel> - <TextBox Height="auto" Grid.Row="5" Grid.ColumnSpan="2" Name="logBox" IsReadOnly="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" /> + <Label Grid.Row="0">OP Identifier</Label> + <Label Grid.Column="1" Grid.Row="0" Name="opIdentifierLabel" ToolTip="Click to copy URI to clipboard" MouseDown="opIdentifierLabel_MouseDown" /> + <Label Grid.Row="1">checkid requests</Label> + <ComboBox Grid.Column="1" Grid.Row="1" Name="checkidRequestList" SelectedIndex="0"> + <ComboBoxItem>Auto respond: Yes</ComboBoxItem> + <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" /> </Grid> </Window> diff --git a/samples/OpenIdOfflineProvider/MainWindow.xaml.cs b/samples/OpenIdOfflineProvider/MainWindow.xaml.cs index d6332dd..a0ee56e 100644 --- a/samples/OpenIdOfflineProvider/MainWindow.xaml.cs +++ b/samples/OpenIdOfflineProvider/MainWindow.xaml.cs @@ -23,6 +23,8 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Provider; using log4net; using log4net.Appender; using log4net.Core; @@ -46,10 +48,13 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { /// </summary> public MainWindow() { this.InitializeComponent(); + this.hostedProvider.ProcessRequest = this.ProcessRequest; TextWriterAppender boxLogger = log4net.LogManager.GetRepository().GetAppenders().OfType<TextWriterAppender>().FirstOrDefault(a => a.Name == "TextBoxAppender"); if (boxLogger != null) { boxLogger.Writer = new TextBoxTextWriter(logBox); } + + this.startProvider(); } #region IDisposable Members @@ -83,34 +88,80 @@ namespace DotNetOpenAuth.OpenIdOfflineProvider { /// </summary> /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param> protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { - this.hostedProvider.StopProvider(); + this.stopProvider(); base.OnClosing(e); } /// <summary> - /// Handles the Click event of the startButton control. + /// Processes an incoming request at the OpenID Provider endpoint. /// </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 startButton_Click(object sender, RoutedEventArgs e) { + /// <param name="requestInfo">The request info.</param> + /// <param name="response">The response.</param> + private void ProcessRequest(HttpRequestInfo requestInfo, HttpListenerResponse response) { + IRequest request = this.hostedProvider.Provider.GetRequest(requestInfo); + if (request == null) { + App.Logger.Error("A request came in that did not carry an OpenID message."); + response.StatusCode = (int)HttpStatusCode.BadRequest; + using (StreamWriter sw = new StreamWriter(response.OutputStream)) { + sw.WriteLine("<html><body>This is an OpenID Provider endpoint.</body></html>"); + } + return; + } + + this.Dispatcher.Invoke((Action)delegate { + if (!request.IsResponseReady) { + var authRequest = request as IAuthenticationRequest; + if (authRequest != null) { + switch (checkidRequestList.SelectedIndex) { + case 0: + if (authRequest.IsDirectedIdentity) { + authRequest.ClaimedIdentifier = new Uri(this.hostedProvider.UserIdentityPageBase, "directedidentity"); + authRequest.LocalIdentifier = authRequest.ClaimedIdentifier; + } + authRequest.IsAuthenticated = true; + break; + case 1: + authRequest.IsAuthenticated = false; + break; + case 2: + IntPtr oldForegroundWindow = NativeMethods.GetForegroundWindow(); + bool stoleFocus = NativeMethods.SetForegroundWindow(this); + CheckIdWindow.ProcessAuthentication(this.hostedProvider, authRequest); + if (stoleFocus) { + NativeMethods.SetForegroundWindow(oldForegroundWindow); + } + break; + } + } + } + }); + + this.hostedProvider.Provider.PrepareResponse(request).Send(response); + } + + /// <summary> + /// Starts the provider. + /// </summary> + private void startProvider() { this.hostedProvider.StartProvider(); - this.portLabel.Content = this.hostedProvider.ProviderEndpoint.Port; - this.opIdentifierLabel.Content = "not yet supported"; // string.Format(url, this.httpHost.Port, OPIdentifier); - this.noIdentity.Content = this.hostedProvider.NegativeIdentitities.First().AbsoluteUri; - this.yesIdentity.Content = this.hostedProvider.AffirmativeIdentities.First().AbsoluteUri; + this.opIdentifierLabel.Content = this.hostedProvider.OPIdentifier; } /// <summary> - /// Handles the Click event of the stopButton control. + /// Stops the provider. /// </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 stopButton_Click(object sender, RoutedEventArgs e) { + private void stopProvider() { this.hostedProvider.StopProvider(); - this.portLabel.Content = string.Empty; - this.noIdentity.Content = string.Empty; - this.yesIdentity.Content = string.Empty; this.opIdentifierLabel.Content = string.Empty; } + + /// <summary> + /// Handles the MouseDown event of the opIdentifierLabel control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param> + private void opIdentifierLabel_MouseDown(object sender, MouseButtonEventArgs e) { + Clipboard.SetText(opIdentifierLabel.Content.ToString()); + } } } diff --git a/samples/OpenIdOfflineProvider/NativeMethods.cs b/samples/OpenIdOfflineProvider/NativeMethods.cs new file mode 100644 index 0000000..ec12819 --- /dev/null +++ b/samples/OpenIdOfflineProvider/NativeMethods.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------- +// <copyright file="NativeMethods.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenIdOfflineProvider { + using System; + using System.Runtime.InteropServices; + using System.Windows; + using System.Windows.Interop; + + internal static class NativeMethods { + /// <summary> + /// Gets the HWND of the current foreground window on the system. + /// </summary> + /// <returns>A handle to the foreground window.</returns> + [DllImport("user32.dll")] + internal static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern IntPtr SetActiveWindow(IntPtr hWnd); + + internal static bool SetForegroundWindow(Window window) { + return SetForegroundWindow(new WindowInteropHelper(window).Handle); + } + + internal static void SetActiveWindow(Window window) { + SetActiveWindow(new WindowInteropHelper(window).Handle); + } + } +} diff --git a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj index aac2441..1bb2367 100644 --- a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj +++ b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj @@ -15,6 +15,7 @@ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <WarningLevel>4</WarningLevel> <UICulture>en-US</UICulture> + <ApplicationIcon>openid.ico</ApplicationIcon> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -56,6 +57,11 @@ <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> + <PropertyGroup Condition=" '$(Sign)' == 'true' "> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\..\src\official-build-key.pfx</AssemblyOriginatorKeyFile> + <DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants> + </PropertyGroup> <ItemGroup> <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> @@ -96,6 +102,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </ApplicationDefinition> + <Page Include="CheckIdWindow.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="MainWindow.xaml"> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> @@ -110,8 +120,12 @@ </Compile> </ItemGroup> <ItemGroup> + <Compile Include="CheckIdWindow.xaml.cs"> + <DependentUpon>CheckIdWindow.xaml</DependentUpon> + </Compile> <Compile Include="HostedProvider.cs" /> <Compile Include="HttpHost.cs" /> + <Compile Include="NativeMethods.cs" /> <Compile Include="Properties\AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> @@ -143,6 +157,9 @@ <Name>DotNetOpenAuth</Name> </ProjectReference> </ItemGroup> + <ItemGroup> + <Resource Include="openid.ico" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/samples/OpenIdOfflineProvider/openid.ico b/samples/OpenIdOfflineProvider/openid.ico Binary files differnew file mode 100644 index 0000000..651aeba --- /dev/null +++ b/samples/OpenIdOfflineProvider/openid.ico |