/// <summary> /// Prepares an identity assertion on behalf of one of this Provider's /// members in order to redirect the user agent to a relying party /// web site and log him/her in immediately in one uninterrupted step. /// </summary> /// <param name="providerEndpoint">The absolute URL on the Provider site that receives OpenID messages.</param> /// <param name="relyingPartyRealm">The URL of the Relying Party web site. /// This will typically be the home page, but may be a longer URL if /// that Relying Party considers the scope of its realm to be more specific. /// The URL provided here must allow discovery of the Relying Party's /// XRDS document that advertises its OpenID RP endpoint.</param> /// <param name="claimedIdentifier">The Identifier you are asserting your member controls.</param> /// <param name="localIdentifier">The Identifier you know your user by internally. This will typically /// be the same as <paramref name="claimedIdentifier" />.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="extensions">The extensions.</param> /// <returns> /// A <see cref="HttpResponseMessage" /> object describing the HTTP response to send /// the user agent to allow the redirect with assertion to happen. /// </returns> public async Task <HttpResponseMessage> PrepareUnsolicitedAssertionAsync(Uri providerEndpoint, Realm relyingPartyRealm, Identifier claimedIdentifier, Identifier localIdentifier, CancellationToken cancellationToken = default(CancellationToken), params IExtensionMessage[] extensions) { Requires.NotNull(providerEndpoint, "providerEndpoint"); Requires.That(providerEndpoint.IsAbsoluteUri, "providerEndpoint", OpenIdStrings.AbsoluteUriRequired); Requires.NotNull(relyingPartyRealm, "relyingPartyRealm"); Requires.NotNull(claimedIdentifier, "claimedIdentifier"); Requires.NotNull(localIdentifier, "localIdentifier"); RequiresEx.ValidState(this.Channel.HostFactories != null); // Although the RP should do their due diligence to make sure that this OP // is authorized to send an assertion for the given claimed identifier, // do due diligence by performing our own discovery on the claimed identifier // and make sure that it is tied to this OP and OP local identifier. if (this.SecuritySettings.UnsolicitedAssertionVerification != ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.NeverVerify) { var serviceEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null); var discoveredEndpoints = await this.discoveryServices.DiscoverAsync(claimedIdentifier, cancellationToken); if (!discoveredEndpoints.Contains(serviceEndpoint)) { Logger.OpenId.WarnFormat( "Failed to send unsolicited assertion for {0} because its discovered services did not include this endpoint: {1}{2}{1}Discovered endpoints: {1}{3}", claimedIdentifier, Environment.NewLine, serviceEndpoint, discoveredEndpoints.ToStringDeferred(true)); // Only FAIL if the setting is set for it. if (this.securitySettings.UnsolicitedAssertionVerification == ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.RequireSuccess) { ErrorUtilities.ThrowProtocol(OpenIdStrings.UnsolicitedAssertionForUnrelatedClaimedIdentifier, claimedIdentifier); } } } Logger.OpenId.InfoFormat("Preparing unsolicited assertion for {0}", claimedIdentifier); RelyingPartyEndpointDescription returnToEndpoint = null; var returnToEndpoints = await relyingPartyRealm.DiscoverReturnToEndpointsAsync(this.Channel.HostFactories, true, cancellationToken); if (returnToEndpoints != null) { returnToEndpoint = returnToEndpoints.FirstOrDefault(); } ErrorUtilities.VerifyProtocol(returnToEndpoint != null, OpenIdStrings.NoRelyingPartyEndpointDiscovered, relyingPartyRealm); var positiveAssertion = new PositiveAssertionResponse(returnToEndpoint) { ProviderEndpoint = providerEndpoint, ClaimedIdentifier = claimedIdentifier, LocalIdentifier = localIdentifier, }; if (extensions != null) { foreach (IExtensionMessage extension in extensions) { positiveAssertion.Extensions.Add(extension); } } Reporting.RecordEventOccurrence(this, "PrepareUnsolicitedAssertion"); return(await this.Channel.PrepareResponseAsync(positiveAssertion, cancellationToken)); }
/// <summary> /// Prepares an identity assertion on behalf of one of this Provider's /// members in order to redirect the user agent to a relying party /// web site and log him/her in immediately in one uninterrupted step. /// </summary> /// <param name="providerEndpoint">The absolute URL on the Provider site that receives OpenID messages.</param> /// <param name="relyingPartyRealm">The URL of the Relying Party web site. /// This will typically be the home page, but may be a longer URL if /// that Relying Party considers the scope of its realm to be more specific. /// The URL provided here must allow discovery of the Relying Party's /// XRDS document that advertises its OpenID RP endpoint.</param> /// <param name="claimedIdentifier">The Identifier you are asserting your member controls.</param> /// <param name="localIdentifier">The Identifier you know your user by internally. This will typically /// be the same as <paramref name="claimedIdentifier" />.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="extensions">The extensions.</param> /// <returns> /// A <see cref="HttpResponseMessage" /> object describing the HTTP response to send /// the user agent to allow the redirect with assertion to happen. /// </returns> public async Task<HttpResponseMessage> PrepareUnsolicitedAssertionAsync(Uri providerEndpoint, Realm relyingPartyRealm, Identifier claimedIdentifier, Identifier localIdentifier, CancellationToken cancellationToken = default(CancellationToken), params IExtensionMessage[] extensions) { Requires.NotNull(providerEndpoint, "providerEndpoint"); Requires.That(providerEndpoint.IsAbsoluteUri, "providerEndpoint", OpenIdStrings.AbsoluteUriRequired); Requires.NotNull(relyingPartyRealm, "relyingPartyRealm"); Requires.NotNull(claimedIdentifier, "claimedIdentifier"); Requires.NotNull(localIdentifier, "localIdentifier"); RequiresEx.ValidState(this.Channel.HostFactories != null); // Although the RP should do their due diligence to make sure that this OP // is authorized to send an assertion for the given claimed identifier, // do due diligence by performing our own discovery on the claimed identifier // and make sure that it is tied to this OP and OP local identifier. if (this.SecuritySettings.UnsolicitedAssertionVerification != ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.NeverVerify) { var serviceEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, localIdentifier, new ProviderEndpointDescription(providerEndpoint, Protocol.Default.Version), null, null); var discoveredEndpoints = await this.discoveryServices.DiscoverAsync(claimedIdentifier, cancellationToken); if (!discoveredEndpoints.Contains(serviceEndpoint)) { Logger.OpenId.WarnFormat( "Failed to send unsolicited assertion for {0} because its discovered services did not include this endpoint: {1}{2}{1}Discovered endpoints: {1}{3}", claimedIdentifier, Environment.NewLine, serviceEndpoint, discoveredEndpoints.ToStringDeferred(true)); // Only FAIL if the setting is set for it. if (this.securitySettings.UnsolicitedAssertionVerification == ProviderSecuritySettings.UnsolicitedAssertionVerificationLevel.RequireSuccess) { ErrorUtilities.ThrowProtocol(OpenIdStrings.UnsolicitedAssertionForUnrelatedClaimedIdentifier, claimedIdentifier); } } } Logger.OpenId.InfoFormat("Preparing unsolicited assertion for {0}", claimedIdentifier); RelyingPartyEndpointDescription returnToEndpoint = null; var returnToEndpoints = await relyingPartyRealm.DiscoverReturnToEndpointsAsync(this.Channel.HostFactories, true, cancellationToken); if (returnToEndpoints != null) { returnToEndpoint = returnToEndpoints.FirstOrDefault(); } ErrorUtilities.VerifyProtocol(returnToEndpoint != null, OpenIdStrings.NoRelyingPartyEndpointDiscovered, relyingPartyRealm); var positiveAssertion = new PositiveAssertionResponse(returnToEndpoint) { ProviderEndpoint = providerEndpoint, ClaimedIdentifier = claimedIdentifier, LocalIdentifier = localIdentifier, }; if (extensions != null) { foreach (IExtensionMessage extension in extensions) { positiveAssertion.Extensions.Add(extension); } } Reporting.RecordEventOccurrence(this, "PrepareUnsolicitedAssertion"); return await this.Channel.PrepareResponseAsync(positiveAssertion, cancellationToken); }