summaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj4
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs6
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/OAuthIdentity.cs63
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/OAuthPrincipal.cs67
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Provider/AnonymousIdentifierProviderBase.cs122
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Provider/AuthenticationRequestExtensions.cs38
-rw-r--r--samples/DotNetOpenAuth.ApplicationBlock/Util.cs13
-rw-r--r--samples/OAuthConsumerWpf/Authorize.xaml12
-rw-r--r--samples/OAuthConsumerWpf/Authorize.xaml.cs59
-rw-r--r--samples/OAuthConsumerWpf/MainWindow.xaml5
-rw-r--r--samples/OAuthConsumerWpf/MainWindow.xaml.cs53
-rw-r--r--samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj24
-rw-r--r--samples/OAuthServiceProvider/App_Code/CustomOAuthTypeProvider.cs5
-rw-r--r--samples/OAuthServiceProvider/App_Code/DataApi.cs20
-rw-r--r--samples/OAuthServiceProvider/App_Code/DataClasses.dbml8
-rw-r--r--samples/OAuthServiceProvider/App_Code/DataClasses.dbml.layout12
-rw-r--r--samples/OAuthServiceProvider/App_Code/DataClasses.designer.cs148
-rw-r--r--samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs23
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs17
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthConsumer.cs41
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs45
-rw-r--r--samples/OAuthServiceProvider/App_Code/OAuthToken.cs64
-rw-r--r--samples/OAuthServiceProvider/App_Code/RequestScopedTokenMessage.cs6
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize.aspx26
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize.aspx.cs11
-rw-r--r--samples/OAuthServiceProvider/Web.config4
-rw-r--r--samples/OpenIdProviderMvc/Code/AnonymousIdentifierProvider.cs25
-rw-r--r--samples/OpenIdProviderMvc/Controllers/HomeController.cs4
-rw-r--r--samples/OpenIdProviderMvc/Controllers/OpenIdController.cs103
-rw-r--r--samples/OpenIdProviderMvc/Controllers/UserController.cs6
-rw-r--r--samples/OpenIdProviderMvc/Global.asax.cs5
-rw-r--r--samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj2
-rw-r--r--samples/OpenIdProviderMvc/Views/Home/PpidXrds.aspx18
-rw-r--r--samples/OpenIdProviderMvc/Views/User/PpidIdentity.aspx2
-rw-r--r--samples/OpenIdProviderMvc/Views/User/PpidXrds.aspx13
-rw-r--r--samples/OpenIdProviderMvc/Web.config12
-rw-r--r--samples/OpenIdProviderWebForms/Web.config7
-rw-r--r--samples/OpenIdRelyingPartyMvc/Web.config5
-rw-r--r--samples/OpenIdRelyingPartyWebForms/MembersOnly/Default.aspx80
-rw-r--r--samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx75
-rw-r--r--samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.cs13
-rw-r--r--samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.designer.cs25
-rw-r--r--samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj8
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Web.config5
-rw-r--r--samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx9
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx.cs10
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs2
48 files changed, 745 insertions, 582 deletions
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
index 570d91f..976a325 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
+++ b/samples/DotNetOpenAuth.ApplicationBlock/DotNetOpenAuth.ApplicationBlock.csproj
@@ -59,11 +59,7 @@
<Compile Include="CustomExtensions\AcmeRequest.cs" />
<Compile Include="CustomExtensions\AcmeResponse.cs" />
<Compile Include="GoogleConsumer.cs" />
- <Compile Include="OAuthIdentity.cs" />
- <Compile Include="OAuthPrincipal.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Provider\AnonymousIdentifierProviderBase.cs" />
- <Compile Include="Provider\AuthenticationRequestExtensions.cs" />
<Compile Include="TwitterConsumer.cs" />
<Compile Include="Util.cs" />
</ItemGroup>
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
index e8511ae..4d3ce13 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/GoogleConsumer.cs
@@ -48,6 +48,7 @@ namespace DotNetOpenAuth.ApplicationBlock {
{ Applications.Finance, "http://finance.google.com/finance/feeds/" },
{ Applications.Gmail, "https://mail.google.com/mail/feed/atom" },
{ Applications.Health, "https://www.google.com/h9/feeds/" },
+ { Applications.Maps, "http://maps.google.com/maps/feeds/" },
{ Applications.OpenSocial, "http://sandbox.gmodules.com/api/" },
{ Applications.PicasaWeb, "http://picasaweb.google.com/data/" },
{ Applications.Spreadsheets, "http://spreadsheets.google.com/feeds/" },
@@ -139,6 +140,11 @@ namespace DotNetOpenAuth.ApplicationBlock {
/// Google Analytics
/// </summary>
Analytics = 0x4000,
+
+ /// <summary>
+ /// Google Maps
+ /// </summary>
+ Maps = 0x8000,
}
/// <summary>
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/OAuthIdentity.cs b/samples/DotNetOpenAuth.ApplicationBlock/OAuthIdentity.cs
deleted file mode 100644
index ea9ec0b..0000000
--- a/samples/DotNetOpenAuth.ApplicationBlock/OAuthIdentity.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthIdentity.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.ApplicationBlock {
- using System;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
-
- /// <summary>
- /// Represents an OAuth consumer that is impersonating a known user on the system.
- /// </summary>
- [Serializable]
- [ComVisible(true)]
- internal class OAuthIdentity : IIdentity {
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthIdentity"/> class.
- /// </summary>
- /// <param name="username">The username.</param>
- internal OAuthIdentity(string username) {
- if (String.IsNullOrEmpty(username)) {
- throw new ArgumentNullException("username");
- }
-
- this.Name = username;
- }
-
- #region IIdentity Members
-
- /// <summary>
- /// Gets the type of authentication used.
- /// </summary>
- /// <value>The constant "OAuth"</value>
- /// <returns>
- /// The type of authentication used to identify the user.
- /// </returns>
- public string AuthenticationType {
- get { return "OAuth"; }
- }
-
- /// <summary>
- /// Gets a value indicating whether the user has been authenticated.
- /// </summary>
- /// <value>The value <c>true</c></value>
- /// <returns>true if the user was authenticated; otherwise, false.
- /// </returns>
- public bool IsAuthenticated {
- get { return true; }
- }
-
- /// <summary>
- /// Gets the name of the user who authorized the OAuth token the consumer is using for authorization.
- /// </summary>
- /// <returns>
- /// The name of the user on whose behalf the code is running.
- /// </returns>
- public string Name { get; private set; }
-
- #endregion
- }
-}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/OAuthPrincipal.cs b/samples/DotNetOpenAuth.ApplicationBlock/OAuthPrincipal.cs
deleted file mode 100644
index 88f3b83..0000000
--- a/samples/DotNetOpenAuth.ApplicationBlock/OAuthPrincipal.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthPrincipal.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.ApplicationBlock {
- using System;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
-
- /// <summary>
- /// Represents an OAuth consumer that is impersonating a known user on the system.
- /// </summary>
- [Serializable]
- [ComVisible(true)]
- internal class OAuthPrincipal : IPrincipal {
- /// <summary>
- /// The roles this user belongs to.
- /// </summary>
- private string[] roles;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class.
- /// </summary>
- /// <param name="identity">The identity.</param>
- /// <param name="roles">The roles this user belongs to.</param>
- internal OAuthPrincipal(OAuthIdentity identity, string[] roles) {
- this.Identity = identity;
- this.roles = roles;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class.
- /// </summary>
- /// <param name="username">The username.</param>
- /// <param name="roles">The roles this user belongs to.</param>
- internal OAuthPrincipal(string username, string[] roles)
- : this(new OAuthIdentity(username), roles) {
- }
-
- #region IPrincipal Members
-
- /// <summary>
- /// Gets the identity of the current principal.
- /// </summary>
- /// <value></value>
- /// <returns>
- /// The <see cref="T:System.Security.Principal.IIdentity"/> object associated with the current principal.
- /// </returns>
- public IIdentity Identity { get; private set; }
-
- /// <summary>
- /// Determines whether the current principal belongs to the specified role.
- /// </summary>
- /// <param name="role">The name of the role for which to check membership.</param>
- /// <returns>
- /// true if the current principal is a member of the specified role; otherwise, false.
- /// </returns>
- public bool IsInRole(string role) {
- return this.roles.Contains(role);
- }
-
- #endregion
- }
-}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Provider/AnonymousIdentifierProviderBase.cs b/samples/DotNetOpenAuth.ApplicationBlock/Provider/AnonymousIdentifierProviderBase.cs
deleted file mode 100644
index 1df7267..0000000
--- a/samples/DotNetOpenAuth.ApplicationBlock/Provider/AnonymousIdentifierProviderBase.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="AnonymousIdentifierProviderBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.ApplicationBlock.Provider {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId;
-
- public abstract class AnonymousIdentifierProviderBase {
- private int newSaltLength = 20;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="AnonymousIdentifierProviderBase"/> class.
- /// </summary>
- /// <param name="baseIdentifier">The base URI on which to append the anonymous part.</param>
- public AnonymousIdentifierProviderBase(Uri baseIdentifier) {
- if (baseIdentifier == null) {
- throw new ArgumentNullException("baseIdentifier");
- }
-
- this.Hasher = HashAlgorithm.Create("SHA256");
- this.Encoder = Encoding.UTF8;
- this.BaseIdentifier = baseIdentifier;
- }
-
- public Uri BaseIdentifier { get; private set; }
-
- protected HashAlgorithm Hasher { get; private set; }
-
- protected Encoding Encoder { get; private set; }
-
- protected int NewSaltLength {
- get {
- return this.newSaltLength;
- }
-
- set {
- if (value <= 0) {
- throw new ArgumentOutOfRangeException("value");
- }
-
- this.newSaltLength = value;
- }
- }
-
- #region IAnonymousIdentifierProvider Members
-
- public Uri GetAnonymousIdentifier(Identifier localIdentifier, Realm relyingPartyRealm) {
- byte[] salt = this.GetHashSaltForLocalIdentifier(localIdentifier);
- string valueToHash = localIdentifier + "#" + (relyingPartyRealm ?? string.Empty);
- byte[] valueAsBytes = this.Encoder.GetBytes(valueToHash);
- byte[] bytesToHash = new byte[valueAsBytes.Length + salt.Length];
- valueAsBytes.CopyTo(bytesToHash, 0);
- salt.CopyTo(bytesToHash, valueAsBytes.Length);
- byte[] hash = this.Hasher.ComputeHash(bytesToHash);
- string base64Hash = Convert.ToBase64String(hash);
- Uri anonymousIdentifier = this.AppendIdentifiers(this.BaseIdentifier, base64Hash);
- return anonymousIdentifier;
- }
-
- #endregion
-
- protected virtual byte[] GetNewSalt() {
- // We COULD use a crypto random function, but for a salt it seems overkill.
- return Util.GetNonCryptoRandomData(this.NewSaltLength);
- }
-
- protected Uri AppendIdentifiers(Uri baseIdentifier, string uriHash) {
- if (baseIdentifier == null) {
- throw new ArgumentNullException("baseIdentifier");
- }
- if (String.IsNullOrEmpty(uriHash)) {
- throw new ArgumentNullException("uriHash");
- }
-
- if (string.IsNullOrEmpty(baseIdentifier.Query)) {
- // The uriHash will appear on the path itself.
- string pathEncoded = Uri.EscapeUriString(uriHash.Replace('/', '_'));
- return new Uri(baseIdentifier, pathEncoded);
- } else {
- // The uriHash will appear on the query string.
- string dataEncoded = Uri.EscapeDataString(uriHash);
- return new Uri(baseIdentifier + dataEncoded);
- }
- }
-
- /// <summary>
- /// Gets the salt to use for generating an anonymous identifier for a given OP local identifier.
- /// </summary>
- /// <param name="localIdentifier">The OP local identifier.</param>
- /// <returns>The salt to use in the hash.</returns>
- /// <remarks>
- /// It is important that this method always return the same value for a given
- /// <paramref name="localIdentifier"/>.
- /// New salts can be generated for local identifiers without previously assigned salt
- /// values by calling <see cref="GetNewSalt"/> or by a custom method.
- /// </remarks>
- protected abstract byte[] GetHashSaltForLocalIdentifier(Identifier localIdentifier);
-
-#if CONTRACTS_FULL
- /// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
- [ContractInvariantMethod]
- protected void ObjectInvariant() {
- Contract.Invariant(this.Hasher != null);
- Contract.Invariant(this.Encoder != null);
- Contract.Invariant(this.BaseIdentifier != null);
- Contract.Invariant(this.NewHashLength > 0);
- }
-#endif
- }
-}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Provider/AuthenticationRequestExtensions.cs b/samples/DotNetOpenAuth.ApplicationBlock/Provider/AuthenticationRequestExtensions.cs
deleted file mode 100644
index a737d30..0000000
--- a/samples/DotNetOpenAuth.ApplicationBlock/Provider/AuthenticationRequestExtensions.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace DotNetOpenAuth.ApplicationBlock.Provider {
- using System;
- using DotNetOpenAuth.OpenId;
- using DotNetOpenAuth.OpenId.Provider;
-
- public static class AuthenticationRequestExtensions {
- /// <summary>
- /// Removes all personally identifiable information from the positive assertion.
- /// </summary>
- /// <param name="request">The incoming authentication request.</param>
- /// <param name="localIdentifier">The OP local identifier, before the anonymous hash is applied to it.</param>
- /// <param name="anonymousIdentifierProvider">The anonymous identifier provider.</param>
- /// <param name="pairwiseUnique">if set to <c>true</c> the anonymous identifier will be unique to the requesting relying party's realm.</param>
- /// <remarks>
- /// The openid.claimed_id and openid.identity values are hashed.
- /// </remarks>
- public static void ScrubPersonallyIdentifiableInformation(this IAuthenticationRequest request, Identifier localIdentifier, AnonymousIdentifierProviderBase anonymousIdentifierProvider, bool pairwiseUnique) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
- if (!request.IsDirectedIdentity) {
- throw new InvalidOperationException("This operation is supported only under identifier select (directed identity) scenarios.");
- }
- if (anonymousIdentifierProvider == null) {
- throw new ArgumentNullException("anonymousIdentifierProvider");
- }
- if (localIdentifier == null) {
- throw new ArgumentNullException("localIdentifier");
- }
-
- // When generating the anonymous identifiers, the openid.identity and openid.claimed_id
- // will always end up with matching values.
- var anonymousIdentifier = anonymousIdentifierProvider.GetAnonymousIdentifier(localIdentifier, pairwiseUnique ? request.Realm : null);
- request.ClaimedIdentifier = anonymousIdentifier;
- request.LocalIdentifier = anonymousIdentifier;
- }
- }
-}
diff --git a/samples/DotNetOpenAuth.ApplicationBlock/Util.cs b/samples/DotNetOpenAuth.ApplicationBlock/Util.cs
index 8a188ac..ea7da97 100644
--- a/samples/DotNetOpenAuth.ApplicationBlock/Util.cs
+++ b/samples/DotNetOpenAuth.ApplicationBlock/Util.cs
@@ -5,8 +5,6 @@
using DotNetOpenAuth.Messaging;
internal static class Util {
- internal static readonly Random NonCryptoRandomDataGenerator = new Random();
-
/// <summary>
/// Enumerates through the individual set bits in a flag enum.
/// </summary>
@@ -30,17 +28,6 @@
}
/// <summary>
- /// Gets a buffer of random data (not cryptographically strong).
- /// </summary>
- /// <param name="length">The length of the sequence to generate.</param>
- /// <returns>The generated values, which may contain zeros.</returns>
- internal static byte[] GetNonCryptoRandomData(int length) {
- byte[] buffer = new byte[length];
- NonCryptoRandomDataGenerator.NextBytes(buffer);
- return buffer;
- }
-
- /// <summary>
/// Copies the contents of one stream to another.
/// </summary>
/// <param name="copyFrom">The stream to copy from, at the position where copying should begin.</param>
diff --git a/samples/OAuthConsumerWpf/Authorize.xaml b/samples/OAuthConsumerWpf/Authorize.xaml
new file mode 100644
index 0000000..5aa2349
--- /dev/null
+++ b/samples/OAuthConsumerWpf/Authorize.xaml
@@ -0,0 +1,12 @@
+<Window x:Class="DotNetOpenAuth.Samples.OAuthConsumerWpf.Authorize"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Title="Authorize" Width="300" ShowInTaskbar="False">
+ <StackPanel>
+ <TextBlock TextWrapping="Wrap">Complete authorization at your service provider,
+ then enter the verification code below and click Finish:</TextBlock>
+ <TextBox Name="verifierBox"/>
+ <Button Name="finishButton" Click="finishButton_Click">Finish</Button>
+ <Button Name="cancelButton" Click="cancelButton_Click">Cancel</Button>
+ </StackPanel>
+</Window>
diff --git a/samples/OAuthConsumerWpf/Authorize.xaml.cs b/samples/OAuthConsumerWpf/Authorize.xaml.cs
new file mode 100644
index 0000000..c28e6cc
--- /dev/null
+++ b/samples/OAuthConsumerWpf/Authorize.xaml.cs
@@ -0,0 +1,59 @@
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Threading;
+ 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 System.Xml.Linq;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// Interaction logic for Authorize.xaml
+ /// </summary>
+ public partial class Authorize : Window {
+ private DesktopConsumer google;
+ private string requestToken;
+
+ internal Authorize(DesktopConsumer consumer) {
+ InitializeComponent();
+
+ this.google = consumer;
+ Cursor original = this.Cursor;
+ this.Cursor = Cursors.Wait;
+ ThreadPool.QueueUserWorkItem(delegate(object state) {
+ Uri browserAuthorizationLocation = GoogleConsumer.RequestAuthorization(
+ this.google,
+ GoogleConsumer.Applications.Contacts | GoogleConsumer.Applications.Blogger,
+ out this.requestToken);
+ System.Diagnostics.Process.Start(browserAuthorizationLocation.AbsoluteUri);
+ this.Dispatcher.BeginInvoke(new Action(() => {
+ this.Cursor = original;
+ finishButton.IsEnabled = true;
+ }));
+ });
+ }
+
+ internal string AccessToken { get; set; }
+
+ private void finishButton_Click(object sender, RoutedEventArgs e) {
+ var grantedAccess = this.google.ProcessUserAuthorization(this.requestToken, verifierBox.Text);
+ this.AccessToken = grantedAccess.AccessToken;
+ DialogResult = true;
+ Close();
+ }
+
+ private void cancelButton_Click(object sender, RoutedEventArgs e) {
+ DialogResult = false;
+ Close();
+ }
+ }
+}
diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml b/samples/OAuthConsumerWpf/MainWindow.xaml
index fb036ce..6ada88a 100644
--- a/samples/OAuthConsumerWpf/MainWindow.xaml
+++ b/samples/OAuthConsumerWpf/MainWindow.xaml
@@ -14,10 +14,7 @@
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
- <StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="3">
- <Button Name="beginAuthorizationButton" Click="beginAuthorizationButton_Click">Start authorize</Button>
- <Button Name="completeAuthorizationButton" Margin="5,0,0,0" Click="completeAuthorizationButton_Click" IsEnabled="false">Complete authorization</Button>
- </StackPanel>
+ <Button Grid.Column="1" Grid.Row="3" Name="beginAuthorizationButton" Click="beginAuthorizationButton_Click">Authorize</Button>
<TabControl Grid.ColumnSpan="2" Grid.Row="4" Name="tabControl1" Margin="0,10,0,0">
<TabItem Header="Gmail Contacts" Name="gmailContactsTab">
<Grid Name="contactsGrid">
diff --git a/samples/OAuthConsumerWpf/MainWindow.xaml.cs b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
index 6c1c2ba..e408d19 100644
--- a/samples/OAuthConsumerWpf/MainWindow.xaml.cs
+++ b/samples/OAuthConsumerWpf/MainWindow.xaml.cs
@@ -30,7 +30,6 @@
public partial class MainWindow : Window {
private InMemoryTokenManager tokenManager = new InMemoryTokenManager();
private DesktopConsumer google;
- private string requestToken;
private string accessToken;
public MainWindow() {
@@ -56,40 +55,26 @@
return;
}
- Cursor original = this.Cursor;
- this.Cursor = Cursors.Wait;
- beginAuthorizationButton.IsEnabled = false;
- ThreadPool.QueueUserWorkItem(delegate(object state) {
- Uri browserAuthorizationLocation = GoogleConsumer.RequestAuthorization(
- this.google,
- GoogleConsumer.Applications.Contacts | GoogleConsumer.Applications.Blogger,
- out this.requestToken);
- System.Diagnostics.Process.Start(browserAuthorizationLocation.AbsoluteUri);
- this.Dispatcher.BeginInvoke(new Action(() => {
- this.Cursor = original;
- beginAuthorizationButton.IsEnabled = true;
- completeAuthorizationButton.IsEnabled = true;
- postButton.IsEnabled = true;
- }));
- });
- }
+ Authorize auth = new Authorize(this.google);
+ bool? result = auth.ShowDialog();
+ if (result.HasValue && result.Value) {
+ this.accessToken = auth.AccessToken;
+ postButton.IsEnabled = true;
- private void completeAuthorizationButton_Click(object sender, RoutedEventArgs e) {
- var grantedAccess = this.google.ProcessUserAuthorization(this.requestToken);
- this.accessToken = grantedAccess.AccessToken;
- XDocument contactsDocument = GoogleConsumer.GetContacts(this.google, grantedAccess.AccessToken);
- var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
- select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
- contactsGrid.Children.Clear();
- foreach (var contact in contacts) {
- contactsGrid.RowDefinitions.Add(new RowDefinition());
- TextBlock name = new TextBlock { Text = contact.Name };
- TextBlock email = new TextBlock { Text = contact.Email };
- Grid.SetRow(name, contactsGrid.RowDefinitions.Count - 1);
- Grid.SetRow(email, contactsGrid.RowDefinitions.Count - 1);
- Grid.SetColumn(email, 1);
- contactsGrid.Children.Add(name);
- contactsGrid.Children.Add(email);
+ XDocument contactsDocument = GoogleConsumer.GetContacts(this.google, this.accessToken);
+ var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
+ select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
+ contactsGrid.Children.Clear();
+ foreach (var contact in contacts) {
+ contactsGrid.RowDefinitions.Add(new RowDefinition());
+ TextBlock name = new TextBlock { Text = contact.Name };
+ TextBlock email = new TextBlock { Text = contact.Email };
+ Grid.SetRow(name, contactsGrid.RowDefinitions.Count - 1);
+ Grid.SetRow(email, contactsGrid.RowDefinitions.Count - 1);
+ Grid.SetColumn(email, 1);
+ contactsGrid.Children.Add(name);
+ contactsGrid.Children.Add(email);
+ }
}
}
diff --git a/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj b/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
index 0617746..6e8e4ea 100644
--- a/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
+++ b/samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj
@@ -65,15 +65,28 @@
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
- <Reference Include="WindowsBase" />
- <Reference Include="PresentationCore" />
- <Reference Include="PresentationFramework" />
+ <Reference Include="UIAutomationProvider">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="PresentationCore">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="PresentationFramework">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Page Include="Authorize.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -88,6 +101,9 @@
</Compile>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Authorize.xaml.cs">
+ <DependentUpon>Authorize.xaml</DependentUpon>
+ </Compile>
<Compile Include="InMemoryTokenManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
@@ -131,4 +147,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project> \ No newline at end of file
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/DataApi.cs b/samples/OAuthServiceProvider/App_Code/DataApi.cs
index a765159..00876f6 100644
--- a/samples/OAuthServiceProvider/App_Code/DataApi.cs
+++ b/samples/OAuthServiceProvider/App_Code/DataApi.cs
@@ -1,20 +1,26 @@
using System.Linq;
using System.ServiceModel;
+/// <summary>
+/// The WCF service API.
+/// </summary>
+/// <remarks>
+/// Note how there is no code here that is bound to OAuth or any other
+/// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+/// And the reference to Global.LoggedInUser is the user being impersonated by the WCF client.
+/// In the OAuth case, it is the user who authorized the OAuth access token that was used
+/// to gain access to the service.
+/// </remarks>
public class DataApi : IDataApi {
- private static OAuthToken AccessToken {
- get { return OperationContext.Current.IncomingMessageProperties["OAuthAccessToken"] as OAuthToken; }
- }
-
public int? GetAge() {
- return AccessToken.User.Age;
+ return Global.LoggedInUser.Age;
}
public string GetName() {
- return AccessToken.User.FullName;
+ return Global.LoggedInUser.FullName;
}
public string[] GetFavoriteSites() {
- return AccessToken.User.FavoriteSites.Select(site => site.SiteUrl).ToArray();
+ return Global.LoggedInUser.FavoriteSites.Select(site => site.SiteUrl).ToArray();
}
}
diff --git a/samples/OAuthServiceProvider/App_Code/DataClasses.dbml b/samples/OAuthServiceProvider/App_Code/DataClasses.dbml
index 0b54d0d..651de9f 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 Name="Callback" Type="System.String" CanBeNull="true" />
+ <Column Name="VerificationCodeFormat" Type="DotNetOpenAuth.OAuth.VerificationCodeFormat" CanBeNull="false" />
+ <Column Name="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..710508d 100644
--- a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
@@ -14,14 +14,30 @@ 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 && t.State != TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State == TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
}
#endregion
@@ -51,6 +67,7 @@ public class DatabaseTokenManager : IServiceProviderTokenManager {
};
Global.DataContext.OAuthTokens.InsertOnSubmit(newToken);
+ Global.DataContext.SubmitChanges();
}
/// <summary>
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
index fce1ad4..1ec2cb5 100644
--- a/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/OAuthAuthorizationManager.cs
@@ -1,7 +1,10 @@
using System;
+using System.Collections.Generic;
+using System.IdentityModel.Policy;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
+using System.ServiceModel.Security;
using DotNetOpenAuth;
using DotNetOpenAuth.OAuth;
@@ -24,10 +27,22 @@ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
if (auth != null) {
var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+ var policy = new OAuthPrincipalAuthorizationPolicy(sp.CreatePrincipal(auth));
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
// Only allow this method call if the access token scope permits it.
string[] scopes = accessToken.Scope.Split('|');
if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
- operationContext.IncomingMessageProperties["OAuthAccessToken"] = accessToken;
return true;
}
}
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/OAuthPrincipalAuthorizationPolicy.cs b/samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..5bd6b05
--- /dev/null
+++ b/samples/OAuthServiceProvider/App_Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Claims;
+using System.IdentityModel.Policy;
+using System.Linq;
+using System.Web;
+using DotNetOpenAuth.OAuth.ChannelElements;
+
+public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly OAuthPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(OAuthPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+}
diff --git a/samples/OAuthServiceProvider/App_Code/OAuthToken.cs b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs
new file mode 100644
index 0000000..fc1d6c5
--- /dev/null
+++ b/samples/OAuthServiceProvider/App_Code/OAuthToken.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------
+// <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, IServiceProviderAccessToken {
+ #region IServiceProviderRequestToken Members
+
+ string IServiceProviderRequestToken.Token {
+ get { return this.Token; }
+ }
+
+ string IServiceProviderRequestToken.ConsumerKey {
+ get { return this.OAuthConsumer.ConsumerKey; }
+ }
+
+ DateTime IServiceProviderRequestToken.CreatedOn {
+ get { return this.IssueDate; }
+ }
+
+ 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
+
+ #region IServiceProviderAccessToken Members
+
+ string IServiceProviderAccessToken.Token {
+ get { return this.Token; }
+ }
+
+ DateTime? IServiceProviderAccessToken.ExpirationDate {
+ get { return null; }
+ }
+
+ string IServiceProviderAccessToken.Username {
+ get { return this.User.OpenIDClaimedIdentifier; }
+ }
+
+ string[] IServiceProviderAccessToken.Roles {
+ get { return this.Scope.Split('|'); }
+ }
+
+ #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;
+ }
}
}
diff --git a/samples/OAuthServiceProvider/Web.config b/samples/OAuthServiceProvider/Web.config
index 894ad38..d039daa 100644
--- a/samples/OAuthServiceProvider/Web.config
+++ b/samples/OAuthServiceProvider/Web.config
@@ -143,7 +143,9 @@
<behavior name="DataApiBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
- <serviceAuthorization serviceAuthorizationManagerType="OAuthAuthorizationManager, __code"/>
+ <serviceAuthorization
+ serviceAuthorizationManagerType="OAuthAuthorizationManager, __code"
+ principalPermissionMode="Custom" />
</behavior>
</serviceBehaviors>
</behaviors>
diff --git a/samples/OpenIdProviderMvc/Code/AnonymousIdentifierProvider.cs b/samples/OpenIdProviderMvc/Code/AnonymousIdentifierProvider.cs
index 2b9e01c..6dc210d 100644
--- a/samples/OpenIdProviderMvc/Code/AnonymousIdentifierProvider.cs
+++ b/samples/OpenIdProviderMvc/Code/AnonymousIdentifierProvider.cs
@@ -1,15 +1,29 @@
namespace OpenIdProviderMvc.Code {
using System;
using System.Web.Security;
- using DotNetOpenAuth.ApplicationBlock.Provider;
using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Provider;
using OpenIdProviderMvc.Models;
- internal class AnonymousIdentifierProvider : AnonymousIdentifierProviderBase {
+ internal class AnonymousIdentifierProvider : PrivatePersonalIdentifierProviderBase {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AnonymousIdentifierProvider"/> class.
+ /// </summary>
internal AnonymousIdentifierProvider()
: base(Util.GetAppPathRootedUri("anon?id=")) {
}
+ /// <summary>
+ /// Gets the salt to use for generating an anonymous identifier for a given OP local identifier.
+ /// </summary>
+ /// <param name="localIdentifier">The OP local identifier.</param>
+ /// <returns>The salt to use in the hash.</returns>
+ /// <remarks>
+ /// It is important that this method always return the same value for a given
+ /// <paramref name="localIdentifier"/>.
+ /// New salts can be generated for local identifiers without previously assigned salt
+ /// values by calling <see cref="CreateSalt"/> or by a custom method.
+ /// </remarks>
protected override byte[] GetHashSaltForLocalIdentifier(Identifier localIdentifier) {
// This is just a sample with no database... a real web app MUST return
// a reasonable salt here and have that salt be persistent for each user.
@@ -17,7 +31,12 @@
string username = User.GetUserFromClaimedIdentifier(new Uri(localIdentifier));
string salt = membership.GetSalt(username);
return Convert.FromBase64String(salt);
- ////return AnonymousIdentifierProviderBase.GetNewSalt(5);
+
+ // If users were encountered without a salt, one could be generated like this,
+ // and would also need to be saved to the user's account.
+ //// var newSalt = AnonymousIdentifierProviderBase.GetNewSalt(5);
+ //// user.Salt = newSalt;
+ //// return newSalt;
}
}
}
diff --git a/samples/OpenIdProviderMvc/Controllers/HomeController.cs b/samples/OpenIdProviderMvc/Controllers/HomeController.cs
index 346e838..5ba08b3 100644
--- a/samples/OpenIdProviderMvc/Controllers/HomeController.cs
+++ b/samples/OpenIdProviderMvc/Controllers/HomeController.cs
@@ -23,9 +23,5 @@
public ActionResult Xrds() {
return View();
}
-
- public ActionResult PpidXrds() {
- return View();
- }
}
}
diff --git a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
index e353268..bd0fdbf 100644
--- a/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
+++ b/samples/OpenIdProviderMvc/Controllers/OpenIdController.cs
@@ -5,9 +5,10 @@ namespace OpenIdProviderMvc.Controllers {
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
- using DotNetOpenAuth.ApplicationBlock.Provider;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Behaviors;
+ using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
using DotNetOpenAuth.OpenId.Provider;
using OpenIdProviderMvc.Code;
@@ -20,67 +21,18 @@ namespace OpenIdProviderMvc.Controllers {
}
[ValidateInput(false)]
- public ActionResult PpidProvider() {
- return this.DoProvider(true);
- }
-
- [ValidateInput(false)]
public ActionResult Provider() {
- return this.DoProvider(false);
- }
-
- [Authorize]
- public ActionResult SendAssertion(bool pseudonymous) {
- IAuthenticationRequest authReq = PendingAuthenticationRequest;
- PendingAuthenticationRequest = null;
- if (authReq == null) {
- throw new InvalidOperationException();
- }
-
- Identifier localIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name);
-
- if (pseudonymous) {
- if (!authReq.IsDirectedIdentity) {
- throw new InvalidOperationException("Directed identity is the only supported scenario for anonymous identifiers.");
- }
-
- var anonProvider = new AnonymousIdentifierProvider();
- authReq.ScrubPersonallyIdentifiableInformation(localIdentifier, anonProvider, true);
- authReq.IsAuthenticated = true;
- } else {
- if (authReq.IsDirectedIdentity) {
- authReq.LocalIdentifier = localIdentifier;
- authReq.ClaimedIdentifier = localIdentifier;
- authReq.IsAuthenticated = true;
- } else {
- if (authReq.LocalIdentifier == localIdentifier) {
- authReq.IsAuthenticated = true;
- if (!authReq.IsDelegatedIdentifier) {
- authReq.ClaimedIdentifier = authReq.LocalIdentifier;
- }
- } else {
- authReq.IsAuthenticated = false;
- }
- }
-
- // TODO: Respond to AX/sreg extension requests here.
- // We don't want to add these extension responses for anonymous identifiers
- // because they could leak information about the user's identity.
- }
-
- return OpenIdProvider.PrepareResponse(authReq).AsActionResult();
- }
-
- private ActionResult DoProvider(bool pseudonymous) {
IRequest request = OpenIdProvider.GetRequest();
if (request != null) {
var authRequest = request as IAuthenticationRequest;
if (authRequest != null) {
PendingAuthenticationRequest = authRequest;
- if (User.Identity.IsAuthenticated && (authRequest.IsDirectedIdentity || Models.User.GetClaimedIdentifierForUser(User.Identity.Name) == authRequest.LocalIdentifier)) {
- return this.SendAssertion(pseudonymous);
+ if (authRequest.IsReturnUrlDiscoverable(OpenIdProvider) == RelyingPartyDiscoveryResult.Success &&
+ User.Identity.IsAuthenticated &&
+ (authRequest.IsDirectedIdentity || this.UserControlsIdentifier(authRequest))) {
+ return this.SendAssertion();
} else {
- return RedirectToAction("LogOn", "Account", new { returnUrl = Url.Action("SendAssertion", new { pseudonymous = pseudonymous }) });
+ return RedirectToAction("LogOn", "Account", new { returnUrl = Url.Action("SendAssertion") });
}
}
@@ -93,5 +45,46 @@ namespace OpenIdProviderMvc.Controllers {
return View();
}
}
+
+ [Authorize]
+ public ActionResult SendAssertion() {
+ IAuthenticationRequest authReq = PendingAuthenticationRequest;
+ PendingAuthenticationRequest = null; // clear session static so we don't do this again
+ if (authReq == null) {
+ throw new InvalidOperationException("There's no pending authentication request!");
+ }
+
+ if (authReq.IsDirectedIdentity) {
+ authReq.LocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name);
+ }
+ if (!authReq.IsDelegatedIdentifier) {
+ authReq.ClaimedIdentifier = authReq.LocalIdentifier;
+ }
+
+ // Respond to AX/sreg extension requests.
+ //// Real web sites would have code here
+
+ authReq.IsAuthenticated = this.UserControlsIdentifier(authReq);
+ return OpenIdProvider.PrepareResponse(authReq).AsActionResult();
+ }
+
+ /// <summary>
+ /// Checks whether the logged in user controls the OP local identifier in the given authentication request.
+ /// </summary>
+ /// <param name="authReq">The authentication request.</param>
+ /// <returns><c>true</c> if the user controls the identifier; <c>false</c> otherwise.</returns>
+ private bool UserControlsIdentifier(IAuthenticationRequest authReq) {
+ if (authReq == null) {
+ throw new ArgumentNullException("authReq");
+ }
+
+ if (User == null || User.Identity == null) {
+ return false;
+ }
+
+ Uri userLocalIdentifier = Models.User.GetClaimedIdentifierForUser(User.Identity.Name);
+ return authReq.LocalIdentifier == userLocalIdentifier ||
+ authReq.LocalIdentifier == PpidGeneration.PpidIdentifierProvider.GetIdentifier(userLocalIdentifier, authReq.Realm);
+ }
}
}
diff --git a/samples/OpenIdProviderMvc/Controllers/UserController.cs b/samples/OpenIdProviderMvc/Controllers/UserController.cs
index c160fce..3cb87ae 100644
--- a/samples/OpenIdProviderMvc/Controllers/UserController.cs
+++ b/samples/OpenIdProviderMvc/Controllers/UserController.cs
@@ -9,7 +9,7 @@ namespace OpenIdProviderMvc.Controllers {
public class UserController : Controller {
public ActionResult PpidIdentity() {
if (Request.AcceptTypes.Contains("application/xrds+xml")) {
- return View("PpidXrds");
+ return View("Xrds");
}
return View();
@@ -33,10 +33,6 @@ namespace OpenIdProviderMvc.Controllers {
return View();
}
- public ActionResult PpidXrds() {
- return View();
- }
-
private ActionResult RedirectIfNotNormalizedRequestUri() {
Uri normalized = Models.User.GetNormalizedClaimedIdentifier(Request.Url);
if (Request.Url != normalized) {
diff --git a/samples/OpenIdProviderMvc/Global.asax.cs b/samples/OpenIdProviderMvc/Global.asax.cs
index 8c57961..a2bcfb2 100644
--- a/samples/OpenIdProviderMvc/Global.asax.cs
+++ b/samples/OpenIdProviderMvc/Global.asax.cs
@@ -26,10 +26,6 @@
"anon",
new { controller = "User", action = "PpidIdentity", id = string.Empty });
routes.MapRoute(
- "PpidXrds",
- "PpidXrds",
- new { controller = "Home", action = "PpidXrds" }); // Parameter defaults
- routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = string.Empty }); // Parameter defaults
@@ -37,6 +33,7 @@
protected void Application_Start() {
RegisterRoutes(RouteTable.Routes);
+ DotNetOpenAuth.OpenId.Behaviors.PpidGeneration.PpidIdentifierProvider = new Code.AnonymousIdentifierProvider();
}
}
} \ No newline at end of file
diff --git a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
index 5caf26d..f568538 100644
--- a/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
+++ b/samples/OpenIdProviderMvc/OpenIdProviderMvc.csproj
@@ -92,10 +92,8 @@
<Content Include="Views\Account\ChangePassword.aspx" />
<Content Include="Views\Account\ChangePasswordSuccess.aspx" />
<Content Include="Views\Account\Register.aspx" />
- <Content Include="Views\Home\PpidXrds.aspx" />
<Content Include="Views\Home\Xrds.aspx" />
<Content Include="Views\OpenId\Provider.aspx" />
- <Content Include="Views\User\PpidXrds.aspx" />
<Content Include="Views\User\PpidIdentity.aspx" />
<Content Include="Views\User\Identity.aspx" />
<Content Include="Views\User\Xrds.aspx" />
diff --git a/samples/OpenIdProviderMvc/Views/Home/PpidXrds.aspx b/samples/OpenIdProviderMvc/Views/Home/PpidXrds.aspx
deleted file mode 100644
index 990a3df..0000000
--- a/samples/OpenIdProviderMvc/Views/Home/PpidXrds.aspx
+++ /dev/null
@@ -1,18 +0,0 @@
-<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?>
-<%--
-This page is a required as part of the service discovery phase of the openid
-protocol (step 1). It simply renders the xml for doing service discovery of
-server.aspx using the xrds mechanism.
-This XRDS doc is discovered via the user.aspx page.
---%>
-<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>
- <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/OpenId/PpidProvider"))%></URI>
- </Service>
- </XRD>
-</xrds:XRDS>
diff --git a/samples/OpenIdProviderMvc/Views/User/PpidIdentity.aspx b/samples/OpenIdProviderMvc/Views/User/PpidIdentity.aspx
index f33a694..655e5d6 100644
--- a/samples/OpenIdProviderMvc/Views/User/PpidIdentity.aspx
+++ b/samples/OpenIdProviderMvc/Views/User/PpidIdentity.aspx
@@ -9,7 +9,7 @@
<op:IdentityEndpoint ID="IdentityEndpoint11" runat="server" ProviderEndpointUrl="~/OpenId/PpidProvider"
ProviderVersion="V11" />
<op:IdentityEndpoint ID="IdentityEndpoint20" runat="server" ProviderEndpointUrl="~/OpenId/PpidProvider"
- XrdsUrl="~/User/all/ppidxrds" XrdsAutoAnswer="false" />
+ XrdsUrl="~/User/all/xrds" XrdsAutoAnswer="false" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>OpenID identity page </h2>
diff --git a/samples/OpenIdProviderMvc/Views/User/PpidXrds.aspx b/samples/OpenIdProviderMvc/Views/User/PpidXrds.aspx
deleted file mode 100644
index 67256bd..0000000
--- a/samples/OpenIdProviderMvc/Views/User/PpidXrds.aspx
+++ /dev/null
@@ -1,13 +0,0 @@
-<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?>
-<XRDS xmlns="xri://$xrds" xmlns:openid="http://openid.net/xmlns/1.0">
- <XRD xmlns="xri://$xrd*($v*2.0)">
- <Service priority="10">
- <Type>http://specs.openid.net/auth/2.0/signon</Type>
- <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/OpenId/PpidProvider"))%></URI>
- </Service>
- <Service priority="20">
- <Type>http://openid.net/signon/1.0</Type>
- <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/OpenId/PpidProvider"))%></URI>
- </Service>
- </XRD>
-</XRDS>
diff --git a/samples/OpenIdProviderMvc/Web.config b/samples/OpenIdProviderMvc/Web.config
index 7b078ef..fb89415 100644
--- a/samples/OpenIdProviderMvc/Web.config
+++ b/samples/OpenIdProviderMvc/Web.config
@@ -46,11 +46,17 @@
<!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
<dotNetOpenAuth>
<openid>
- <relyingParty>
- <security requireSsl="false"/>
+ <provider>
+ <security requireSsl="false" />
+ <behaviors>
+ <!-- Behaviors activate themselves automatically for individual matching requests.
+ The first one in this list to match an incoming request "owns" the request. If no
+ profile matches, the default behavior is assumed. -->
+ <add type="DotNetOpenAuth.OpenId.Behaviors.PpidGeneration, DotNetOpenAuth" />
+ </behaviors>
<!-- Uncomment the following to activate the sample custom store. -->
<!--<store type="RelyingPartyWebForms.CustomStore, RelyingPartyWebForms" />-->
- </relyingParty>
+ </provider>
</openid>
<messaging>
<untrustedWebRequest>
diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config
index 7626751..c3c7ef9 100644
--- a/samples/OpenIdProviderWebForms/Web.config
+++ b/samples/OpenIdProviderWebForms/Web.config
@@ -47,6 +47,13 @@
<dotNetOpenAuth>
<openid>
<provider>
+ <security requireSsl="false" />
+ <behaviors>
+ <!-- Behaviors activate themselves automatically for individual matching requests.
+ The first one in this list to match an incoming request "owns" the request. If no
+ profile matches, the default behavior is assumed. -->
+ <!--<add type="DotNetOpenAuth.OpenId.Behaviors.PpidGeneration, DotNetOpenAuth" />-->
+ </behaviors>
<!-- Uncomment the following to activate the sample custom store. -->
<!--<store type="OpenIdProviderWebForms.Code.CustomStore, OpenIdProviderWebForms" />-->
</provider>
diff --git a/samples/OpenIdRelyingPartyMvc/Web.config b/samples/OpenIdRelyingPartyMvc/Web.config
index ba97122..c4a4b71 100644
--- a/samples/OpenIdRelyingPartyMvc/Web.config
+++ b/samples/OpenIdRelyingPartyMvc/Web.config
@@ -47,6 +47,11 @@
<openid>
<relyingParty>
<security requireSsl="false" />
+ <behaviors>
+ <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+ with OPs that use Attribute Exchange (in various formats). -->
+ <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
+ </behaviors>
</relyingParty>
</openid>
<messaging>
diff --git a/samples/OpenIdRelyingPartyWebForms/MembersOnly/Default.aspx b/samples/OpenIdRelyingPartyWebForms/MembersOnly/Default.aspx
index 46458e8..cbc13ee 100644
--- a/samples/OpenIdRelyingPartyWebForms/MembersOnly/Default.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/MembersOnly/Default.aspx
@@ -1,6 +1,6 @@
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" %>
<%@ Import Namespace="OpenIdRelyingPartyWebForms" %>
-
+<%@ Register Src="~/MembersOnly/ProfileFieldsDisplay.ascx" TagPrefix="cc1" TagName="ProfileFieldsDisplay" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
<h2>
Members Only Area
@@ -22,85 +22,13 @@
</ul>
<% } %>
-<% if (State.ProfileFields != null) { %>
+<% if (State.ProfileFields != null) {
+ profileFieldsDisplay.ProfileValues = State.ProfileFields; %>
<p>
In addition to authenticating you, your OpenID Provider may
have told us something about you using the
Simple Registration extension:
</p>
- <table id="profileFieldsTable" runat="server">
- <tr>
- <td>
- Nickname
- </td>
- <td>
- <%=State.ProfileFields.Nickname %>
- </td>
- </tr>
- <tr>
- <td>
- Email
- </td>
- <td>
- <%=State.ProfileFields.Email%>
- </td>
- </tr>
- <tr>
- <td>
- FullName
- </td>
- <td>
- <%=State.ProfileFields.FullName%>
- </td>
- </tr>
- <tr>
- <td>
- Date of Birth
- </td>
- <td>
- <%=State.ProfileFields.BirthDate.ToString()%>
- </td>
- </tr>
- <tr>
- <td>
- Gender
- </td>
- <td>
- <%=State.ProfileFields.Gender.ToString()%>
- </td>
- </tr>
- <tr>
- <td>
- Post Code
- </td>
- <td>
- <%=State.ProfileFields.PostalCode%>
- </td>
- </tr>
- <tr>
- <td>
- Country
- </td>
- <td>
- <%=State.ProfileFields.Country%>
- </td>
- </tr>
- <tr>
- <td>
- Language
- </td>
- <td>
- <%=State.ProfileFields.Language%>
- </td>
- </tr>
- <tr>
- <td>
- Timezone
- </td>
- <td>
- <%=State.ProfileFields.TimeZone%>
- </td>
- </tr>
- </table>
+ <cc1:ProfileFieldsDisplay runat="server" ID="profileFieldsDisplay" />
<% } %>
</asp:Content>
diff --git a/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx
new file mode 100644
index 0000000..b2e5f7e
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx
@@ -0,0 +1,75 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ProfileFieldsDisplay.ascx.cs" Inherits="OpenIdRelyingPartyWebForms.MembersOnly.ProfileFieldsDisplay" %>
+<table id="profileFieldsTable" runat="server">
+ <tr>
+ <td>
+ Nickname
+ </td>
+ <td>
+ <%=ProfileValues.Nickname %>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Email
+ </td>
+ <td>
+ <%=ProfileValues.Email%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ FullName
+ </td>
+ <td>
+ <%=ProfileValues.FullName%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Date of Birth
+ </td>
+ <td>
+ <%=ProfileValues.BirthDate.ToString()%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Gender
+ </td>
+ <td>
+ <%=ProfileValues.Gender.ToString()%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Post Code
+ </td>
+ <td>
+ <%=ProfileValues.PostalCode%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Country
+ </td>
+ <td>
+ <%=ProfileValues.Country%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Language
+ </td>
+ <td>
+ <%=ProfileValues.Language%>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Timezone
+ </td>
+ <td>
+ <%=ProfileValues.TimeZone%>
+ </td>
+ </tr>
+</table>
diff --git a/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.cs b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.cs
new file mode 100644
index 0000000..4fb127e
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.cs
@@ -0,0 +1,13 @@
+namespace OpenIdRelyingPartyWebForms.MembersOnly {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
+
+ public partial class ProfileFieldsDisplay : System.Web.UI.UserControl {
+ public ClaimsResponse ProfileValues { get; set; }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.designer.cs b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.designer.cs
new file mode 100644
index 0000000..4a5dc8a
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/MembersOnly/ProfileFieldsDisplay.ascx.designer.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4918
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdRelyingPartyWebForms.MembersOnly {
+
+
+ public partial class ProfileFieldsDisplay {
+
+ /// <summary>
+ /// profileFieldsTable control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTable profileFieldsTable;
+ }
+}
diff --git a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
index 556dadf..d3bf92c 100644
--- a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
+++ b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
@@ -132,6 +132,13 @@
<Compile Include="MembersOnly\DisplayGoogleContacts.aspx.designer.cs">
<DependentUpon>DisplayGoogleContacts.aspx</DependentUpon>
</Compile>
+ <Compile Include="MembersOnly\ProfileFieldsDisplay.ascx.cs">
+ <DependentUpon>ProfileFieldsDisplay.ascx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="MembersOnly\ProfileFieldsDisplay.ascx.designer.cs">
+ <DependentUpon>ProfileFieldsDisplay.ascx</DependentUpon>
+ </Compile>
<Compile Include="m\Login.aspx.cs">
<DependentUpon>Login.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -168,6 +175,7 @@
<Content Include="images\yahoo.png" />
<Content Include="loginPlusOAuth.aspx" />
<Content Include="MembersOnly\DisplayGoogleContacts.aspx" />
+ <Content Include="MembersOnly\ProfileFieldsDisplay.ascx" />
<Content Include="MembersOnly\Web.config" />
<Content Include="m\Login.aspx" />
<Content Include="NoIdentityOpenId.aspx" />
diff --git a/samples/OpenIdRelyingPartyWebForms/Web.config b/samples/OpenIdRelyingPartyWebForms/Web.config
index 2a13828..0ae3c6c 100644
--- a/samples/OpenIdRelyingPartyWebForms/Web.config
+++ b/samples/OpenIdRelyingPartyWebForms/Web.config
@@ -29,6 +29,11 @@
<openid>
<relyingParty>
<security requireSsl="false" />
+ <behaviors>
+ <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+ with OPs that use Attribute Exchange (in various formats). -->
+ <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
+ </behaviors>
<!-- Uncomment the following to activate the sample custom store. -->
<!--<store type="OpenIdRelyingPartyWebForms.CustomStore, OpenIdRelyingPartyWebForms" />-->
</relyingParty>
diff --git a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
index de82304..df29914 100644
--- a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
@@ -8,7 +8,7 @@
{
width: 200px;
}
-.openidtextbox
+input.openidtextbox
{
width: 185px;
}
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx b/samples/OpenIdRelyingPartyWebForms/login.aspx
index 20294e7..281725c 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx
@@ -5,7 +5,7 @@
<asp:Content runat="server" ContentPlaceHolderID="Main">
<h2>Login Page </h2>
<rp:OpenIdLogin ID="OpenIdLogin1" runat="server" CssClass="openid_login" RequestCountry="Request"
- RequestEmail="Request" RequestGender="Require" RequestPostalCode="Require" RequestTimeZone="Require"
+ RequestEmail="Require" RequestGender="Require" RequestPostalCode="Require" RequestTimeZone="Require"
RememberMeVisible="True" PolicyUrl="~/PrivacyPolicy.aspx" TabIndex="1"
OnLoggedIn="OpenIdLogin1_LoggedIn" OnLoggingIn="OpenIdLogin1_LoggingIn"
OnSetupRequired="OpenIdLogin1_SetupRequired" />
@@ -13,17 +13,20 @@
<asp:CheckBox ID="requireSslCheckBox" runat="server"
Text="RequireSsl (high security) mode"
oncheckedchanged="requireSslCheckBox_CheckedChanged" /><br />
+ <h4 style="margin-top: 0; margin-bottom: 0">PAPE policies</h4>
<asp:CheckBoxList runat="server" ID="papePolicies">
<asp:ListItem Text="Request phishing resistant authentication" Value="http://schemas.openid.net/pape/policies/2007/06/phishing-resistant" />
<asp:ListItem Text="Request multi-factor authentication" Value="http://schemas.openid.net/pape/policies/2007/06/multi-factor" />
<asp:ListItem Text="Request physical multi-factor authentication" Value="http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical" />
+ <asp:ListItem Text="Request PPID identifier" Value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" />
</asp:CheckBoxList>
+ <p>Try the PPID identifier functionality against the OpenIDProviderMvc sample.</p>
</fieldset>
<br />
<asp:Label ID="setupRequiredLabel" runat="server" EnableViewState="False" Text="You must log into your Provider first to use Immediate mode."
Visible="False" />
<p>
- <asp:ImageButton runat="server" ImageUrl="~/images/yahoo.png" ID="yahooLoginButton"
- OnClick="yahooLoginButton_Click" />
+ <rp:OpenIdButton runat="server" ImageUrl="~/images/yahoo.png" Text="Login with Yahoo!" ID="yahooLoginButton"
+ Identifier="https://me.yahoo.com/" />
</p>
</asp:Content>
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx.cs b/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
index fb961dd..1de942a 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
@@ -39,16 +39,6 @@ namespace OpenIdRelyingPartyWebForms {
this.setupRequiredLabel.Visible = true;
}
- protected void yahooLoginButton_Click(object sender, ImageClickEventArgs e) {
- OpenIdRelyingParty openid = new OpenIdRelyingParty();
- var req = openid.CreateRequest("yahoo.com");
- this.prepareRequest(req);
- req.RedirectToProvider();
-
- // We don't listen for the response from the provider explicitly
- // because the OpenIdLogin control is already doing that for us.
- }
-
private void prepareRequest(IAuthenticationRequest request) {
// Collect the PAPE policies requested by the user.
List<string> policies = new List<string>();
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
index 60de3ff..944f5ff 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
@@ -56,6 +56,6 @@ namespace OpenIdRelyingPartyWebForms {
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
- protected global::System.Web.UI.WebControls.ImageButton yahooLoginButton;
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdButton yahooLoginButton;
}
}