public ActionResult Index() { var openId = new OpenIdRelyingParty(); IAuthenticationResponse response = openId.GetResponse(); // if this is a roundtrip and we got something back from the provider... if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: { FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false); break; } case AuthenticationStatus.Canceled: { ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; } case AuthenticationStatus.Failed: { ModelState.AddModelError("loginIdentifier", "Login failed at the provider"); break; } } } return View(); }
public static void Register(OpenIdRelyingParty relyingParty) { if (relyingParty == null) { throw new ArgumentNullException("relyingParty"); } relyingParty.ExtensionFactories.Add(new Acme()); }
public ActionResult Login() { var openId = new OpenIdRelyingParty(); var response = openId.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: var user = BlogService.GetOrCreateUser(response); return FinishAuthentication(user); case AuthenticationStatus.Canceled: throw new Exception("Login was cancelled at the provider"); case AuthenticationStatus.Failed: throw new Exception("Login failed using the provided OpenID identifier"); default: throw new NotImplementedException(); } } return View(GetViewModel()); }
public ActionResult Login(LoginViewModel model) { if (!Identifier.IsValid(model.IdentityProviderUri)) { throw new Exception("The specified login identifier is invalid"); } var openId = new OpenIdRelyingParty(); var request = openId.CreateRequest(Identifier.Parse(model.IdentityProviderUri)); request.AddExtension(new ClaimsRequest { BirthDate = DemandLevel.NoRequest, Email = DemandLevel.Request, FullName = DemandLevel.NoRequest, TimeZone = DemandLevel.Request, Nickname = DemandLevel.Request, Country = DemandLevel.NoRequest, Gender = DemandLevel.NoRequest, Language = DemandLevel.NoRequest, PostalCode = DemandLevel.NoRequest }); return request.RedirectingResponse.AsActionResult(); }
/// <summary> /// Creates a relying party that does not verify incoming messages against /// nonce or association stores. /// </summary> /// <returns>The instantiated <see cref="OpenIdRelyingParty"/>.</returns> /// <remarks> /// Useful for previewing messages while /// allowing them to be fully processed and verified later. /// </remarks> internal static OpenIdRelyingParty CreateNonVerifying() { OpenIdRelyingParty rp = new OpenIdRelyingParty(); rp.Channel = new OpenIdChannel(null, null, rp.SecuritySettings); return(rp); }
private static OpenIdRelyingParty openid; // = new OpenIdRelyingParty(); #endregion Fields #region Constructors static GoogleOAuth() { if (System.Web.HttpContext.Current != null) { openid = new OpenIdRelyingParty(); } }
void LoginToGoogle() { try { using (OpenIdRelyingParty party = new OpenIdRelyingParty()) { IAuthenticationRequest request = party.CreateRequest(ConfigurationManager.AppSettings["google-auth-path"]); var fetch = new FetchRequest(); fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email); fetch.Attributes.AddRequired(WellKnownAttributes.Name.First); fetch.Attributes.AddRequired(WellKnownAttributes.Name.Last); request.AddExtension(fetch); //request.AddExtension(new ClaimsRequest //{ // Country = DemandLevel.Request, // Email = DemandLevel.Request, // Gender = DemandLevel.Require, // PostalCode = DemandLevel.Require, // TimeZone = DemandLevel.Require, //}); request.RedirectToProvider(); } } catch (ProtocolException ex) { LabelStatus.Text = ex.Message; } }
public ActionResult Login() { var openid = new OpenIdRelyingParty(); IAuthenticationResponse response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: var user = EnsureUserExists(response); FormsAuthentication.RedirectFromLoginPage( user.email, false); break; case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
protected void Page_Load(object sender, EventArgs e) { using (var openid = new OpenIdRelyingParty()) { // In order to receive the UIRequest as a response, we must register a custom extension factory. openid.ExtensionFactories.Add(new UIRequestAtRelyingPartyFactory()); var response = openid.GetResponse(); if (response == null) { // Submit an OpenID request which Google must reply to immediately. // If the user hasn't established a trust relationship with this site yet, // Google will not give us the user identity, but they will tell us whether the user // at least has an active login session with them so we know whether to promote the // "Log in with Google" button. IAuthenticationRequest request = openid.CreateRequest("https://www.google.com/accounts/o8/id"); request.AddExtension(new UIRequest { Mode = UIModeDetectSession }); request.Mode = AuthenticationRequestMode.Immediate; request.RedirectToProvider(); } else { if (response.Status == AuthenticationStatus.Authenticated) { this.YouTrustUsLabel.Visible = true; } else if (response.Status == AuthenticationStatus.SetupRequired) { // Google refused to authenticate the user without user interaction. // This is either because Google doesn't know who the user is yet, // or because the user hasn't indicated to Google to trust this site. // Google uniquely offers the RP a tip as to which of the above situations is true. // Figure out which it is. In a real app, you might use this value to promote a // Google login button on your site if you detect that a Google session exists. var ext = response.GetUntrustedExtension<UIRequest>(); this.YouAreLoggedInLabel.Visible = ext != null && ext.Mode == UIModeDetectSession; this.YouAreNotLoggedInLabel.Visible = !this.YouAreLoggedInLabel.Visible; } } } }
public ActionResult Authenticate(string returnUrl) { var rp = new OpenIdRelyingParty(); var response = rp.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: // Make sure we have a user account for this guy. string identifier = response.ClaimedIdentifier; // convert to string so LinqToSQL expression parsing works. if (MvcApplication.DataContext.Users.FirstOrDefault(u => u.OpenIDClaimedIdentifier == identifier) == null) { MvcApplication.DataContext.Users.InsertOnSubmit(new User { OpenIDFriendlyIdentifier = response.FriendlyIdentifierForDisplay, OpenIDClaimedIdentifier = response.ClaimedIdentifier, }); } FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false); return this.Redirect(returnUrl ?? Url.Action("Index", "Home")); default: ModelState.AddModelError(string.Empty, "An error occurred during login."); break; } } return this.View("LogOn"); }
protected override void Initialize(RequestContext requestContext) { if (FormsService == null) { FormsService = new FormsAuthenticationService(); } if (OpenId == null) { OpenId = new OpenIdRelyingParty(); } base.Initialize(requestContext); }
/// <summary> /// Constructor. /// </summary> public UserController(IUserRepository users, IUserAuthService authService, ILogger logger) : base(authService, logger) { _openId = new OpenIdRelyingParty(); _logger = logger; _users = users; }
// // GET: /LogOn/ public ActionResult LogOn() { var openid = new OpenIdRelyingParty(); var response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: var fetch = response.GetExtension<FetchResponse>(); if (fetch != null) { foreach (var attribute in fetch.Attributes) { ViewData.Add(attribute.TypeUri, string.Join("|", attribute.Values)); } } //response.ClaimedIdentifier //return RedirectToAction("LogOn"); break; case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
/// <summary> /// Creates a relying party that does not verify incoming messages against /// nonce or association stores. /// </summary> /// <returns>The instantiated <see cref="OpenIdRelyingParty"/>.</returns> /// <remarks> /// Useful for previewing messages while /// allowing them to be fully processed and verified later. /// </remarks> internal static OpenIdRelyingParty CreateNonVerifying() { OpenIdRelyingParty rp = new OpenIdRelyingParty(); rp.Channel = OpenIdChannel.CreateNonVerifyingChannel(); return(rp); }
public void IsValidLogin(Uri serviceUri) { var result = false; var openid = new OpenIdRelyingParty(); if (openid.GetResponse() == null) { // Stage 2: user submitting Identifier openid.CreateRequest(HttpRequest.Request.Form["openid_identifier"]).RedirectToProvider(); } else { // Stage 3: OpenID Provider sending assertion response switch (openid.Response.Status) { case AuthenticationStatus.Authenticated: FormsAuthenticationProvider.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false); break; case AuthenticationStatus.Canceled: ViewData["Message"] = "Canceled at provider"; RenderView("Login"); break; case AuthenticationStatus.Failed: ViewData["Message"] = openid.Response.Exception.Message; RenderView("Login"); break; } } }
public IAuthenticationRequest CreateRequest(string realmUrl, string returnUrl) { if (!Uri.IsWellFormedUriString(realmUrl, UriKind.Relative)) { throw new ArgumentException("Value is not a well formed relative uri string", "realmUrl"); } if (!Uri.IsWellFormedUriString(returnUrl, UriKind.Relative)) { throw new ArgumentException("Value is not a well formed relative uri string", "returnUrl"); } IAuthenticationRequest request; var baseUri = new Uri(_request.Url, "/"); var realmUri = new Uri(baseUri, realmUrl); var returnToUri = new Uri(baseUri, returnUrl); using (var openIdRelyingParty = new OpenIdRelyingParty()) { request = openIdRelyingParty.CreateRequest(Identifier.Parse("https://www.google.com/accounts/o8/id"), new Realm(realmUri), returnToUri); } request.AddExtension(new ClaimsRequest { Email = DemandLevel.Require }); return request; }
public ActionResult LogOn(string from) { var openid = new OpenIdRelyingParty(); IAuthenticationResponse response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: var sreg = response.GetExtension<ClaimsResponse>(); if (sreg != null) { Session.Add("Email", sreg.Email); Session.Add("FullName", sreg.FullName); } FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false); break; case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
protected void beginButton_Click(object sender, EventArgs e) { this.RegisterAsyncTask( new PageAsyncTask( async ct => { if (!this.Page.IsValid) { return; // don't login if custom validation failed. } try { using (OpenIdRelyingParty rp = new OpenIdRelyingParty()) { var request = await rp.CreateRequestAsync(this.openIdBox.Text, new HttpRequestWrapper(Request), Response.ClientDisconnectedToken); request.IsExtensionOnly = true; // This is where you would add any OpenID extensions you wanted // to include in the request. request.AddExtension( new ClaimsRequest { Email = DemandLevel.Request, Country = DemandLevel.Request, Gender = DemandLevel.Require, PostalCode = DemandLevel.Require, TimeZone = DemandLevel.Require, }); await request.RedirectToProviderAsync(new HttpContextWrapper(Context), Response.ClientDisconnectedToken); } } catch (ProtocolException ex) { // The user probably entered an Identifier that // was not a valid OpenID endpoint. this.openidValidator.Text = ex.Message; this.openidValidator.IsValid = false; } })); }
public ActionResult Index() { ViewData["Authenticated"] = "FALSE"; using (OpenIdRelyingParty openid = new OpenIdRelyingParty()) { var response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: ViewData["Authenticated"] = "TRUE"; break; case AuthenticationStatus.Canceled: ViewData["Authenticated"] = "Cancelled"; break; case AuthenticationStatus.Failed: ViewData["Authenticated"] = "FAILED"; break; } } } return View(); }
/// <summary> /// Authenicates a user based on the information in the HTTP request. /// </summary> /// <returns></returns> public override GraywulfPrincipal Authenticate() { // Get OpenID provider's response from the http context using (var openid = new OpenIdRelyingParty()) { var response = openid.GetResponse(); // TODO: figure out which OpenID provider sent the response // and associate with the right authenticator if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: return CreatePrincipal(response); case AuthenticationStatus.Canceled: case AuthenticationStatus.Failed: throw new System.Security.Authentication.AuthenticationException("OpenID authentication failed.", response.Exception); case AuthenticationStatus.ExtensionsOnly: case AuthenticationStatus.SetupRequired: throw new InvalidOperationException(); default: throw new NotImplementedException(); } } return null; } }
public ActionResult SignIn() { var openid = new OpenIdRelyingParty(); var response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: var claimsResponse = response.GetExtension<ClaimsResponse>(); FormsAuthentication.SetAuthCookie(claimsResponse.Email, true); return RedirectToAction("Index", "Member"); case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
public ActionResult SignIn(string openIdProviderUrl) { if (!Identifier.IsValid(openIdProviderUrl)) { ModelState.AddModelError("loginIdentifier", "The specified login identifier is invalid"); return View(); } if (ModelState.IsValid) { var openid = new OpenIdRelyingParty(); var identifier = Identifier.Parse(openIdProviderUrl); var thisUri = Request.Url; //var returnUri = new Uri(string.Format("{0}://{1}:{2}{3}", thisUri.Scheme, thisUri.Host, thisUri.Port, returnUrl)); var request = openid.CreateRequest(identifier, Realm.AutoDetect, thisUri); // Require some additional data request.AddExtension(new ClaimsRequest { Email = DemandLevel.Require, FullName = DemandLevel.Require }); return request.RedirectingResponse.AsActionResult(); } return View(); }
public ActionResult LogOn() { var openid = new OpenIdRelyingParty(); IAuthenticationResponse response = openid.GetResponse(); var page = HttpContext.Items["page"] = "/"; if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: FormsAuthentication.SetAuthCookie(response.GetExtension<ClaimsResponse>().Email, false); return Redirect("~" + response.GetCallbackArgument("redirectPage")); break; case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
protected void beginButton_Click(object sender, EventArgs e) { if (!this.Page.IsValid) { return; // don't login if custom validation failed. } try { using (OpenIdRelyingParty rp = new OpenIdRelyingParty()) { var request = rp.CreateRequest(this.openIdBox.Text); request.IsExtensionOnly = true; // This is where you would add any OpenID extensions you wanted // to include in the request. request.AddExtension(new ClaimsRequest { Country = DemandLevel.Request, Gender = DemandLevel.Require, PostalCode = DemandLevel.Require, TimeZone = DemandLevel.Require, }); request.RedirectToProvider(); } } catch (ProtocolException ex) { // The user probably entered an Identifier that // was not a valid OpenID endpoint. this.openidValidator.Text = ex.Message; this.openidValidator.IsValid = false; } }
/// <summary> /// Verifies that the positive assertion data matches the results of /// discovery on the Claimed Identifier. /// </summary> /// <param name="relyingParty">The relying party.</param> /// <exception cref="ProtocolException"> /// Thrown when the Provider is asserting that a user controls an Identifier /// when discovery on that Identifier contradicts what the Provider says. /// This would be an indication of either a misconfigured Provider or /// an attempt by someone to spoof another user's identity with a rogue Provider. /// </exception> private void VerifyDiscoveryMatchesAssertion(OpenIdRelyingParty relyingParty) { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. Identifier claimedId = this.Response.ClaimedIdentifier; if (relyingParty.SecuritySettings.RequireSsl) { if (!claimedId.TryRequireSsl(out claimedId)) { Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); } } // While it LOOKS like we're performing discovery over HTTP again // Yadis.IdentifierDiscoveryCachePolicy is set to HttpRequestCacheLevel.CacheIfAvailable // which means that the .NET runtime is caching our discoveries for us. This turns out // to be very fast and keeps our code clean and easily verifiable as correct and secure. // CAUTION: if this discovery is ever made to be skipped based on previous discovery // data that was saved to the return_to URL, be careful to verify that that information // is signed by the RP before it's considered reliable. In 1.x stateless mode, this RP // doesn't (and can't) sign its own return_to URL, so its cached discovery information // is merely a hint that must be verified by performing discovery again here. var discoveryResults = relyingParty.Discover(claimedId); ErrorUtilities.VerifyProtocol( discoveryResults.Contains(this.Endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.Endpoint, discoveryResults.ToStringDeferred(true)); }
/// <summary> /// Authenicates a user based on the information in the HTTP request. /// </summary> /// <returns></returns> public override void Authenticate(AuthenticationRequest request, AuthenticationResponse response) { // Only execute the authentication if the user is not known yet if (response.Principal == null) { // Get OpenID provider's response from the http context using (var openid = new OpenIdRelyingParty()) { var openIDResponse = openid.GetResponse(); // TODO: figure out which OpenID provider sent the response // and associate with the right authenticator if (response != null) { switch (openIDResponse.Status) { case AuthenticationStatus.Authenticated: response.SetPrincipal(CreatePrincipal(openIDResponse)); break; case AuthenticationStatus.Canceled: case AuthenticationStatus.Failed: throw new System.Security.Authentication.AuthenticationException("OpenID authentication failed.", openIDResponse.Exception); // TODO case AuthenticationStatus.ExtensionsOnly: case AuthenticationStatus.SetupRequired: throw new InvalidOperationException(); default: throw new NotImplementedException(); } } } } }
public ActionResult BeginAuth() { var provider = "http://steamcommunity.com/openid"; var realm = new DotNetOpenAuth.OpenId.Realm(string.Format("{0}{1}{2}", this.Request.Url.Scheme, Uri.SchemeDelimiter, this.Request.Url.Authority)); var returnTo = new Uri(this.Request.Url, this.Url.Action("EndAuth")); using (var rp = new OpenIdRelyingParty()) { var request = rp.CreateRequest(provider, realm, returnTo); var claimsRequest = new ClaimsRequest { Email = DemandLevel.Require, BirthDate = DemandLevel.Request, Country = DemandLevel.Request, FullName = DemandLevel.Request, Gender = DemandLevel.Request, Language = DemandLevel.Request, Nickname = DemandLevel.Request, PostalCode = DemandLevel.Request, TimeZone = DemandLevel.Request, }; request.AddExtension(claimsRequest); return request.RedirectingResponse.AsActionResult(); } }
// // GET: /Account/LogOn public ActionResult LogOn() { var openid = new OpenIdRelyingParty(); IAuthenticationResponse response = openid.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: RedirectFromLoginPage( response.ClaimedIdentifier, "LogOn"); break; case AuthenticationStatus.Canceled: ModelState.AddModelError("loginIdentifier", "Login was cancelled at the provider"); break; case AuthenticationStatus.Failed: ModelState.AddModelError("loginIdentifier", "Login failed using the provided OpenID identifier"); break; } } return View(); }
// // GET: /Home/ //STEAM_0:0:68926576 //SteamWebAPI.SetGlobalKey("CFDCF16D4EC9D68762FBE9C61B43892D"); //vmykel //wheniwasyourman public ActionResult Index() { OpenIdRelyingParty openid = new OpenIdRelyingParty(); OpenIdLogin openlog = new OpenIdLogin(); openid.SecuritySettings.AllowDualPurposeIdentifiers = true; IAuthenticationResponse response = openid.GetResponse(); if (response != null) { string regex = Request.QueryString["openid.identity"]; //string youareel= "http://steamcommunity.com/openid/id/76561198131281243"; string[] str = regex.Split('/'); string id = str[5]; Session["user"] = id; FormsAuthentication.SetAuthCookie(id, false); if(!User.Identity.IsAuthenticated) { return RedirectToAction("Index"); } if (User.Identity.IsAuthenticated) { return RedirectToAction("Index","Account"); } } if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "Account"); } return View(); }
public async Task UnsolicitedAssertion() { var opStore = new StandardProviderApplicationStore(); Handle(RPUri).By( async req => { var rp = new OpenIdRelyingParty(new StandardRelyingPartyApplicationStore(), this.HostFactories); IAuthenticationResponse response = await rp.GetResponseAsync(req); Assert.That(response, Is.Not.Null); Assert.AreEqual(AuthenticationStatus.Authenticated, response.Status); return new HttpResponseMessage(); }); Handle(OPUri).By( async (req, ct) => { var op = new OpenIdProvider(opStore, this.HostFactories); return await this.AutoProviderActionAsync(op, req, ct); }); this.RegisterMockRPDiscovery(ssl: false); { var op = new OpenIdProvider(opStore, this.HostFactories); Identifier id = GetMockIdentifier(ProtocolVersion.V20); var assertion = await op.PrepareUnsolicitedAssertionAsync(OPUri, RPRealmUri, id, OPLocalIdentifiers[0]); using (var httpClient = this.HostFactories.CreateHttpClient()) { using (var response = await httpClient.GetAsync(assertion.Headers.Location)) { response.EnsureSuccessStatusCode(); } } } }
void DoLoad() { OpenIdRelyingParty openid = new OpenIdRelyingParty(); var response = openid.GetResponse(); if (response == null) return; switch (response.Status) { case AuthenticationStatus.Authenticated: var fetch = response.GetExtension<FetchResponse>(); Session["claim"] = response.ClaimedIdentifier; Session["user"] = GetUserDetail(fetch); // This is where you would look for any OpenID extension responses included // in the authentication assertion. //var claimsResponse = response.GetExtension<ClaimsResponse>(); //Database.ProfileFields = claimsResponse; // Store off the "friendly" username to display -- NOT for username lookup //Database.FriendlyLoginName = response.FriendlyIdentifierForDisplay; // Use FormsAuthentication to tell ASP.NET that the user is now logged in, // with the OpenID Claimed Identifier as their username. FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, false); break; case AuthenticationStatus.Canceled: break; case AuthenticationStatus.Failed: break; } LabelStatus.Text = string.Format("Status : {0}", response.Status); }
public void ExtensionFactories() { var rp = new OpenIdRelyingParty(null); var factories = rp.ExtensionFactories; Assert.IsNotNull(factories); Assert.AreEqual(1, factories.Count); Assert.IsInstanceOf<StandardOpenIdExtensionFactory>(factories[0]); }
private ActionResult MakeRequest(string loginIdentifier) { if (!Identifier.IsValid(loginIdentifier)) { TempData.FlashError("The loginIdentifier is not valid."); return RedirectToAction("SignIn", "Authentication"); } else { var openid = new OpenIdRelyingParty(); var replyTo = Url.Action("CompleteRequest", "OpenId", null, Request.Url.Scheme); var replyToUri = new Uri(replyTo, UriKind.Absolute); var request = openid.CreateRequest( Identifier.Parse(loginIdentifier), Realm.AutoDetect, replyToUri); // Require some additional data request.AddExtension(new ClaimsRequest { BirthDate = DemandLevel.NoRequest, Email = DemandLevel.Require, FullName = DemandLevel.Require }); return request.RedirectingResponse.AsActionResult(); } }
/// <summary> /// Initializes a new instance of the <see cref="PositiveAuthenticationResponse"/> class /// after verifying that discovery on the identifier matches the asserted data. /// </summary> /// <param name="response">The response.</param> /// <param name="relyingParty">The relying party.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The newly initialized instance.</returns> internal static async Task <PositiveAuthenticationResponse> CreateAsync( PositiveAssertionResponse response, OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { var result = new PositiveAuthenticationResponse(response, relyingParty); await result.VerifyDiscoveryMatchesAssertionAsync(relyingParty, cancellationToken); return(result); }
public static PositiveAuthenticationResponse1 CreateAsync_ccp( PositiveAssertionResponse response, OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { var result = new PositiveAuthenticationResponse1(response, relyingParty); GlobalState.claimedEndPoint = result.Endpoint; result.VerifyDiscoveryMatchesAssertionAsync_ccp(relyingParty, cancellationToken); return(result); }
public static PositiveAuthenticationResponse1 CreateAsync_ccp( PositiveAssertionResponse response, OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { var result = new PositiveAuthenticationResponse1(response, relyingParty); result.VerifyDiscoveryMatchesAssertionAsync_ccp(relyingParty, cancellationToken); //Contract.Assert(false); return(result); }
/// <summary> /// Creates a relying party that does not verify incoming messages against /// nonce or association stores. /// </summary> /// <returns>The instantiated <see cref="OpenIdRelyingParty"/>.</returns> /// <remarks> /// Useful for previewing messages while /// allowing them to be fully processed and verified later. /// </remarks> internal static OpenIdRelyingParty CreateNonVerifying() { OpenIdRelyingParty rp = new OpenIdRelyingParty(); try { rp.Channel = OpenIdRelyingPartyChannel.CreateNonVerifyingChannel(); return(rp); } catch { rp.Dispose(); throw; } }
private void VerifyDiscoveryMatchesAssertionAsync_ccp(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { Identifier claimedId = this.Response.ClaimedIdentifier; var discoveryResults = relyingParty.Discover(claimedId, cancellationToken); if (!discoveryResults.Contains(this.Endpoint)) { Contract.Assume(false); } GloabalState.is_endpoint_discovered = true; }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationRequest"/> class. /// </summary> /// <param name="endpoint">The endpoint that describes the OpenID Identifier and Provider that will complete the authentication.</param> /// <param name="realm">The realm, or root URL, of the host web site.</param> /// <param name="returnToUrl">The base return_to URL that the Provider should return the user to to complete authentication. This should not include callback parameters as these should be added using the <see cref="AddCallbackArguments(string, string)"/> method.</param> /// <param name="relyingParty">The relying party that created this instance.</param> private AuthenticationRequest(ServiceEndpoint endpoint, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint"); ErrorUtilities.VerifyArgumentNotNull(realm, "realm"); ErrorUtilities.VerifyArgumentNotNull(returnToUrl, "returnToUrl"); ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); this.endpoint = endpoint; this.RelyingParty = relyingParty; this.Realm = realm; this.ReturnToUrl = returnToUrl; this.Mode = AuthenticationRequestMode.Setup; }
/// <summary> /// Performs identifier discovery, creates associations and generates authentication requests /// on-demand for as long as new ones can be generated based on the results of Identifier discovery. /// </summary> /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> /// <param name="relyingParty">The relying party.</param> /// <param name="realm">The realm.</param> /// <param name="returnToUrl">The return_to base URL.</param> /// <param name="createNewAssociationsAsNeeded">if set to <c>true</c>, associations that do not exist between this Relying Party and the asserting Providers are created before the authentication request is created.</param> /// <returns>A sequence of authentication requests, any of which constitutes a valid identity assertion on the Claimed Identifier.</returns> internal static IEnumerable <AuthenticationRequest> Create(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, bool createNewAssociationsAsNeeded) { // We have a long data validation and preparation process ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); ErrorUtilities.VerifyArgumentNotNull(realm, "realm"); // Normalize the portion of the return_to path that correlates to the realm for capitalization. // (so that if a web app base path is /MyApp/, but the URL of this request happens to be // /myapp/login.aspx, we bump up the return_to Url to use /MyApp/ so it matches the realm. UriBuilder returnTo = new UriBuilder(returnToUrl); if (returnTo.Path.StartsWith(realm.AbsolutePath, StringComparison.OrdinalIgnoreCase) && !returnTo.Path.StartsWith(realm.AbsolutePath, StringComparison.Ordinal)) { returnTo.Path = realm.AbsolutePath + returnTo.Path.Substring(realm.AbsolutePath.Length); returnToUrl = returnTo.Uri; } userSuppliedIdentifier = userSuppliedIdentifier.TrimFragment(); if (relyingParty.SecuritySettings.RequireSsl) { // Rather than check for successful SSL conversion at this stage, // We'll wait for secure discovery to fail on the new identifier. userSuppliedIdentifier.TryRequireSsl(out userSuppliedIdentifier); } if (Logger.IsWarnEnabled && returnToUrl.Query != null) { NameValueCollection returnToArgs = HttpUtility.ParseQueryString(returnToUrl.Query); foreach (string key in returnToArgs) { if (OpenIdRelyingParty.IsOpenIdSupportingParameter(key)) { Logger.WarnFormat("OpenID argument \"{0}\" found in return_to URL. This can corrupt an OpenID response.", key); } } } // Throw an exception now if the realm and the return_to URLs don't match // as required by the provider. We could wait for the provider to test this and // fail, but this will be faster and give us a better error message. ErrorUtilities.VerifyProtocol(realm.Contains(returnToUrl), OpenIdStrings.ReturnToNotUnderRealm, returnToUrl, realm); // Perform discovery right now (not deferred). var serviceEndpoints = userSuppliedIdentifier.Discover(relyingParty.WebRequestHandler); // Call another method that defers request generation. return(CreateInternal(userSuppliedIdentifier, relyingParty, realm, returnToUrl, serviceEndpoints, createNewAssociationsAsNeeded)); }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationRequest"/> class. /// </summary> /// <param name="discoveryResult">The endpoint that describes the OpenID Identifier and Provider that will complete the authentication.</param> /// <param name="realm">The realm, or root URL, of the host web site.</param> /// <param name="returnToUrl">The base return_to URL that the Provider should return the user to to complete authentication. This should not include callback parameters as these should be added using the <see cref="AddCallbackArguments(string, string)"/> method.</param> /// <param name="relyingParty">The relying party that created this instance.</param> private AuthenticationRequest(IdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { Requires.NotNull(discoveryResult, "discoveryResult"); Requires.NotNull(realm, "realm"); Requires.NotNull(returnToUrl, "returnToUrl"); Requires.NotNull(relyingParty, "relyingParty"); this.DiscoveryResult = discoveryResult; this.RelyingParty = relyingParty; this.Realm = realm; this.ReturnToUrl = returnToUrl; this.Mode = AuthenticationRequestMode.Setup; }
/// <summary> /// Initializes a new instance of the <see cref="AuthenticationRequest"/> class. /// </summary> /// <param name="discoveryResult">The endpoint that describes the OpenID Identifier and Provider that will complete the authentication.</param> /// <param name="realm">The realm, or root URL, of the host web site.</param> /// <param name="returnToUrl">The base return_to URL that the Provider should return the user to to complete authentication. This should not include callback parameters as these should be added using the <see cref="AddCallbackArguments(string, string)"/> method.</param> /// <param name="relyingParty">The relying party that created this instance.</param> private AuthenticationRequest(IdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) { Contract.Requires <ArgumentNullException>(discoveryResult != null); Contract.Requires <ArgumentNullException>(realm != null); Contract.Requires <ArgumentNullException>(returnToUrl != null); Contract.Requires <ArgumentNullException>(relyingParty != null); this.DiscoveryResult = discoveryResult; this.RelyingParty = relyingParty; this.Realm = realm; this.ReturnToUrl = returnToUrl; this.Mode = AuthenticationRequestMode.Setup; }
/// <summary> /// Initializes a new instance of the <see cref="PositiveAuthenticationResponse"/> class /// </summary> /// <param name="response">The positive assertion response that was just received by the Relying Party.</param> /// <param name="relyingParty">The relying party.</param> private PositiveAuthenticationResponse(PositiveAssertionResponse response, OpenIdRelyingParty relyingParty) : base(response) { Requires.NotNull(relyingParty, "relyingParty"); this.Endpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( this.Response.ClaimedIdentifier, this.Response.GetReturnToArgument(AuthenticationRequest.UserSuppliedIdentifierParameterName), this.Response.LocalIdentifier, new ProviderEndpointDescription(this.Response.ProviderEndpoint, this.Response.Version), null, null); Logger.OpenId.InfoFormat("Received identity assertion for {0} via {1}.", this.Response.ClaimedIdentifier, this.Provider.Uri); }
/// <summary> /// Creates the relying party instance used to generate authentication requests. /// </summary> /// <returns>The instantiated relying party.</returns> private OpenIdRelyingParty CreateRelyingParty() { // If we're in stateful mode, first use the explicitly given one on this control if there // is one. Then try the configuration file specified one. Finally, use the default // in-memory one that's built into OpenIdRelyingParty. IRelyingPartyApplicationStore store = this.Stateless ? null : (this.CustomApplicationStore ?? DotNetOpenAuthSection.Configuration.OpenId.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore)); var rp = new OpenIdRelyingParty(store); // Only set RequireSsl to true, as we don't want to override // a .config setting of true with false. if (this.RequireSsl) { rp.SecuritySettings.RequireSsl = true; } return(rp); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (this.nonVerifyingRelyingParty != null) { this.nonVerifyingRelyingParty.Dispose(); this.nonVerifyingRelyingParty = null; } // Tear off the instance member as a local variable for thread safety. IDisposable disposableChannel = this.channel as IDisposable; if (disposableChannel != null) { disposableChannel.Dispose(); } } }
/// <summary> /// Initializes a new instance of the <see cref="PositiveAuthenticationResponse"/> class. /// </summary> /// <param name="response">The positive assertion response that was just received by the Relying Party.</param> /// <param name="relyingParty">The relying party.</param> internal PositiveAuthenticationResponse(PositiveAssertionResponse response, OpenIdRelyingParty relyingParty) { ErrorUtilities.VerifyArgumentNotNull(response, "response"); ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); this.response = response; this.relyingParty = relyingParty; this.endpoint = ServiceEndpoint.CreateForClaimedIdentifier( this.response.ClaimedIdentifier, this.response.GetReturnToArgument(AuthenticationRequest.UserSuppliedIdentifierParameterName), this.response.LocalIdentifier, new ProviderEndpointDescription(this.response.ProviderEndpoint, this.response.Version), null, null); this.VerifyDiscoveryMatchesAssertion(); }
/// <summary> /// Verifies that the positive assertion data matches the results of /// discovery on the Claimed Identifier. /// </summary> /// <param name="relyingParty">The relying party.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// A task that completes with the asynchronous operation. /// </returns> /// <exception cref="ProtocolException">Thrown when the Provider is asserting that a user controls an Identifier /// when discovery on that Identifier contradicts what the Provider says. /// This would be an indication of either a misconfigured Provider or /// an attempt by someone to spoof another user's identity with a rogue Provider.</exception> private async Task VerifyDiscoveryMatchesAssertionAsync(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. Identifier claimedId = this.Response.ClaimedIdentifier; if (relyingParty.SecuritySettings.RequireSsl) { if (!claimedId.TryRequireSsl(out claimedId)) { Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); } } // Check whether this particular identifier presents a problem with HTTP discovery // due to limitations in the .NET Uri class. UriIdentifier claimedIdUri = claimedId as UriIdentifier; if (claimedIdUri != null && claimedIdUri.ProblematicNormalization) { ErrorUtilities.VerifyProtocol(relyingParty.SecuritySettings.AllowApproximateIdentifierDiscovery, OpenIdStrings.ClaimedIdentifierDefiesDotNetNormalization); Logger.OpenId.WarnFormat("Positive assertion for claimed identifier {0} cannot be precisely verified under partial trust hosting due to .NET limitation. An approximate verification will be attempted.", claimedId); } // While it LOOKS like we're performing discovery over HTTP again // Yadis.IdentifierDiscoveryCachePolicy is set to HttpRequestCacheLevel.CacheIfAvailable // which means that the .NET runtime is caching our discoveries for us. This turns out // to be very fast and keeps our code clean and easily verifiable as correct and secure. // CAUTION: if this discovery is ever made to be skipped based on previous discovery // data that was saved to the return_to URL, be careful to verify that that information // is signed by the RP before it's considered reliable. In 1.x stateless mode, this RP // doesn't (and can't) sign its own return_to URL, so its cached discovery information // is merely a hint that must be verified by performing discovery again here. var discoveryResults = await relyingParty.DiscoverAsync(claimedId, cancellationToken); ErrorUtilities.VerifyProtocol( discoveryResults.Contains(this.Endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.Endpoint, discoveryResults.ToStringDeferred(true)); }
//ERIC'S CODE //private async Task VerifyDiscoveryMatchesAssertionAsync_ccp(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) public async Task VerifyDiscoveryMatchesAssertionAsync_ccp(OpenIdRelyingParty relyingParty, CancellationToken cancellationToken) { Logger.OpenId.Debug("Verifying assertion matches identifier discovery results..."); // Ensure that we abide by the RP's rules regarding RequireSsl for this discovery step. Identifier claimedId = this.Response.ClaimedIdentifier; /* * if (relyingParty.SecuritySettings.RequireSsl) * { * if (!claimedId.TryRequireSsl(out claimedId)) * { * Logger.OpenId.ErrorFormat("This site is configured to accept only SSL-protected OpenIDs, but {0} was asserted and must be rejected.", this.Response.ClaimedIdentifier); * ErrorUtilities.ThrowProtocol(OpenIdStrings.RequireSslNotSatisfiedByAssertedClaimedId, this.Response.ClaimedIdentifier); * } * } */ // Check whether this particular identifier presents a problem with HTTP discovery // due to limitations in the .NET Uri class. UriIdentifier claimedIdUri = claimedId as UriIdentifier; /* * if (claimedIdUri != null && claimedIdUri.ProblematicNormalization) * { * ErrorUtilities.VerifyProtocol(relyingParty.SecuritySettings.AllowApproximateIdentifierDiscovery, OpenIdStrings.ClaimedIdentifierDefiesDotNetNormalization); * Logger.OpenId.WarnFormat("Positive assertion for claimed identifier {0} cannot be precisely verified under partial trust hosting due to .NET limitation. An approximate verification will be attempted.", claimedId); * } */ var discoveryResults = await relyingParty.DiscoverAsync(claimedId, cancellationToken); ErrorUtilities.VerifyProtocol( discoveryResults.Contains(this.Endpoint), OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery, this.Endpoint, discoveryResults.ToStringDeferred(true)); }
/// <summary> /// Gets all the callback arguments that were previously added using /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/> or as a natural part /// of the return_to URL. /// </summary> /// <returns>A name-value dictionary. Never null.</returns> /// <remarks> /// Callback parameters are only available if they are complete and untampered with /// since the original request message (as proven by a signature). /// If the relying party is operating in stateless mode an empty dictionary is always /// returned since the callback arguments could not be signed to protect against /// tampering. /// </remarks> public IDictionary <string, string> GetUntrustedCallbackArguments() { var args = new Dictionary <string, string>(); // Return all the return_to arguments, except for the OpenID-supporting ones. // The only arguments that should be returned here are the ones that the host // web site adds explicitly. foreach (string key in this.response.GetReturnToParameterNames().Where(key => !OpenIdRelyingParty.IsOpenIdSupportingParameter(key))) { args[key] = this.response.GetReturnToArgument(key); } return(args); }
public PositiveAuthenticationResponse(PositiveAssertionResponse r, OpenIdRelyingParty re) { _Endpoint = p.NondetIdentifierDiscoveryResult(); }
/// <summary> /// Returns a filtered and sorted list of the available OP endpoints for a discovered Identifier. /// </summary> /// <param name="endpoints">The endpoints.</param> /// <param name="relyingParty">The relying party.</param> /// <returns>A filtered and sorted list of endpoints; may be empty if the input was empty or the filter removed all endpoints.</returns> private static List <IdentifierDiscoveryResult> FilterAndSortEndpoints(IEnumerable <IdentifierDiscoveryResult> endpoints, OpenIdRelyingParty relyingParty) { Contract.Requires <ArgumentNullException>(endpoints != null); Contract.Requires <ArgumentNullException>(relyingParty != null); // Construct the endpoints filters based on criteria given by the host web site. EndpointSelector versionFilter = ep => ep.Version >= Protocol.Lookup(relyingParty.SecuritySettings.MinimumRequiredOpenIdVersion).Version; EndpointSelector hostingSiteFilter = relyingParty.EndpointFilter ?? (ep => true); bool anyFilteredOut = false; var filteredEndpoints = new List <IdentifierDiscoveryResult>(); foreach (var endpoint in endpoints) { if (versionFilter(endpoint) && hostingSiteFilter(endpoint)) { filteredEndpoints.Add(endpoint); } else { anyFilteredOut = true; } } // Sort endpoints so that the first one in the list is the most preferred one. filteredEndpoints.OrderBy(ep => ep, relyingParty.EndpointOrder); var endpointList = new List <IdentifierDiscoveryResult>(filteredEndpoints.Count); foreach (var endpoint in filteredEndpoints) { endpointList.Add(endpoint); } if (anyFilteredOut) { Logger.Yadis.DebugFormat("Some endpoints were filtered out. Total endpoints remaining: {0}", filteredEndpoints.Count); } if (Logger.Yadis.IsDebugEnabled) { if (MessagingUtilities.AreEquivalent(endpoints, endpointList)) { Logger.Yadis.Debug("Filtering and sorting of endpoints did not affect the list."); } else { Logger.Yadis.Debug("After filtering and sorting service endpoints, this is the new prioritized list:"); Logger.Yadis.Debug(Util.ToStringDeferred(filteredEndpoints, true)); } } return(endpointList); }
/// <summary> /// Returns a filtered and sorted list of the available OP endpoints for a discovered Identifier. /// </summary> /// <param name="endpoints">The endpoints.</param> /// <param name="relyingParty">The relying party.</param> /// <returns>A filtered and sorted list of endpoints; may be empty if the input was empty or the filter removed all endpoints.</returns> private static List <ServiceEndpoint> FilterAndSortEndpoints(IEnumerable <ServiceEndpoint> endpoints, OpenIdRelyingParty relyingParty) { ErrorUtilities.VerifyArgumentNotNull(endpoints, "endpoints"); ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty"); // Construct the endpoints filters based on criteria given by the host web site. EndpointSelector versionFilter = ep => ((ServiceEndpoint)ep).Protocol.Version >= Protocol.Lookup(relyingParty.SecuritySettings.MinimumRequiredOpenIdVersion).Version; EndpointSelector hostingSiteFilter = relyingParty.EndpointFilter ?? (ep => true); bool anyFilteredOut = false; var filteredEndpoints = new List <IXrdsProviderEndpoint>(); foreach (ServiceEndpoint endpoint in endpoints) { if (versionFilter(endpoint) && hostingSiteFilter(endpoint)) { filteredEndpoints.Add(endpoint); } else { anyFilteredOut = true; } } // Sort endpoints so that the first one in the list is the most preferred one. filteredEndpoints.Sort(relyingParty.EndpointOrder); List <ServiceEndpoint> endpointList = new List <ServiceEndpoint>(filteredEndpoints.Count); foreach (ServiceEndpoint endpoint in filteredEndpoints) { endpointList.Add(endpoint); } if (anyFilteredOut) { Logger.DebugFormat("Some endpoints were filtered out. Total endpoints remaining: {0}", filteredEndpoints.Count); } if (Logger.IsDebugEnabled) { if (MessagingUtilities.AreEquivalent(endpoints, endpointList)) { Logger.Debug("Filtering and sorting of endpoints did not affect the list."); } else { Logger.Debug("After filtering and sorting service endpoints, this is the new prioritized list:"); Logger.Debug(Util.ToStringDeferred(filteredEndpoints, true)); } } return(endpointList); }
/// <summary> /// Performs deferred request generation for the <see cref="Create"/> method. /// </summary> /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> /// <param name="relyingParty">The relying party.</param> /// <param name="realm">The realm.</param> /// <param name="returnToUrl">The return_to base URL.</param> /// <param name="serviceEndpoints">The discovered service endpoints on the Claimed Identifier.</param> /// <param name="createNewAssociationsAsNeeded">if set to <c>true</c>, associations that do not exist between this Relying Party and the asserting Providers are created before the authentication request is created.</param> /// <returns> /// A sequence of authentication requests, any of which constitutes a valid identity assertion on the Claimed Identifier. /// </returns> /// <remarks> /// All data validation and cleansing steps must have ALREADY taken place /// before calling this method. /// </remarks> private static IEnumerable <AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable <ServiceEndpoint> serviceEndpoints, bool createNewAssociationsAsNeeded) { Logger.InfoFormat("Performing discovery on user-supplied identifier: {0}", userSuppliedIdentifier); IEnumerable <ServiceEndpoint> endpoints = FilterAndSortEndpoints(serviceEndpoints, relyingParty); // Maintain a list of endpoints that we could not form an association with. // We'll fallback to generating requests to these if the ones we CAN create // an association with run out. var failedAssociationEndpoints = new List <ServiceEndpoint>(0); foreach (var endpoint in endpoints) { Logger.InfoFormat("Creating authentication request for user supplied Identifier: {0}", userSuppliedIdentifier); Logger.DebugFormat("Realm: {0}", realm); Logger.DebugFormat("Return To: {0}", returnToUrl); // The strategy here is to prefer endpoints with whom we can create associations. Association association = null; if (relyingParty.AssociationManager.HasAssociationStore) { // In some scenarios (like the AJAX control wanting ALL auth requests possible), // we don't want to create associations with every Provider. But we'll use // associations where they are already formed from previous authentications. association = createNewAssociationsAsNeeded ? relyingParty.AssociationManager.GetOrCreateAssociation(endpoint.ProviderDescription) : relyingParty.AssociationManager.GetExistingAssociation(endpoint.ProviderDescription); if (association == null && createNewAssociationsAsNeeded) { Logger.WarnFormat("Failed to create association with {0}. Skipping to next endpoint.", endpoint.ProviderEndpoint); // No association could be created. Add it to the list of failed association // endpoints and skip to the next available endpoint. failedAssociationEndpoints.Add(endpoint); continue; } } yield return(new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty)); } // Now that we've run out of endpoints that respond to association requests, // since we apparently are still running, the caller must want another request. // We'll go ahead and generate the requests to OPs that may be down. if (failedAssociationEndpoints.Count > 0) { Logger.WarnFormat("Now generating requests for Provider endpoints that failed initial association attempts."); foreach (var endpoint in failedAssociationEndpoints) { Logger.WarnFormat("Creating authentication request for user supplied Identifier: {0}", userSuppliedIdentifier); Logger.DebugFormat("Realm: {0}", realm); Logger.DebugFormat("Return To: {0}", returnToUrl); // Create the auth request, but prevent it from attempting to create an association // because we've already tried. Let's not have it waste time trying again. var authRequest = new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty); authRequest.associationPreference = AssociationPreference.IfAlreadyEstablished; yield return(authRequest); } } }
public PositiveAuthenticationResponse1(PositiveAssertionResponse response, OpenIdRelyingParty relyingParty) : base(response, relyingParty) { }
/// <summary> /// Performs identifier discovery, creates associations and generates authentication requests /// on-demand for as long as new ones can be generated based on the results of Identifier discovery. /// </summary> /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> /// <param name="relyingParty">The relying party.</param> /// <param name="realm">The realm.</param> /// <param name="returnToUrl">The return_to base URL.</param> /// <param name="createNewAssociationsAsNeeded">if set to <c>true</c>, associations that do not exist between this Relying Party and the asserting Providers are created before the authentication request is created.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// A sequence of authentication requests, any of which constitutes a valid identity assertion on the Claimed Identifier. /// Never null, but may be empty. /// </returns> internal static async Task <IEnumerable <AuthenticationRequest> > CreateAsync(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, bool createNewAssociationsAsNeeded, CancellationToken cancellationToken) { Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); Requires.NotNull(relyingParty, "relyingParty"); Requires.NotNull(realm, "realm"); // Normalize the portion of the return_to path that correlates to the realm for capitalization. // (so that if a web app base path is /MyApp/, but the URL of this request happens to be // /myapp/login.aspx, we bump up the return_to Url to use /MyApp/ so it matches the realm. UriBuilder returnTo = new UriBuilder(returnToUrl); if (returnTo.Path.StartsWith(realm.AbsolutePath, StringComparison.OrdinalIgnoreCase) && !returnTo.Path.StartsWith(realm.AbsolutePath, StringComparison.Ordinal)) { returnTo.Path = realm.AbsolutePath + returnTo.Path.Substring(realm.AbsolutePath.Length); returnToUrl = returnTo.Uri; } userSuppliedIdentifier = userSuppliedIdentifier.TrimFragment(); if (relyingParty.SecuritySettings.RequireSsl) { // Rather than check for successful SSL conversion at this stage, // We'll wait for secure discovery to fail on the new identifier. if (!userSuppliedIdentifier.TryRequireSsl(out userSuppliedIdentifier)) { // But at least log the failure. Logger.OpenId.WarnFormat("RequireSsl mode is on, so discovery on insecure identifier {0} will yield no results.", userSuppliedIdentifier); } } if (Logger.OpenId.IsWarnEnabled && returnToUrl.Query != null) { NameValueCollection returnToArgs = HttpUtility.ParseQueryString(returnToUrl.Query); foreach (string key in returnToArgs) { if (OpenIdRelyingParty.IsOpenIdSupportingParameter(key)) { Logger.OpenId.WarnFormat("OpenID argument \"{0}\" found in return_to URL. This can corrupt an OpenID response.", key); } } } // Throw an exception now if the realm and the return_to URLs don't match // as required by the provider. We could wait for the provider to test this and // fail, but this will be faster and give us a better error message. ErrorUtilities.VerifyProtocol(realm.Contains(returnToUrl), OpenIdStrings.ReturnToNotUnderRealm, returnToUrl, realm); // Perform discovery right now (not deferred). IEnumerable <IdentifierDiscoveryResult> serviceEndpoints; try { var identifierDiscoveryResults = await relyingParty.DiscoverAsync(userSuppliedIdentifier, cancellationToken); var results = identifierDiscoveryResults.CacheGeneratedResults(); // If any OP Identifier service elements were found, we must not proceed // to use any Claimed Identifier services, per OpenID 2.0 sections 7.3.2.2 and 11.2. // For a discussion on this topic, see // http://groups.google.com/group/dotnetopenid/browse_thread/thread/4b5a8c6b2210f387/5e25910e4d2252c8 // Usually the Discover method we called will automatically filter this for us, but // just to be sure, we'll do it here as well since the RP may be configured to allow // these dual identifiers for assertion verification purposes. var opIdentifiers = results.Where(result => result.ClaimedIdentifier == result.Protocol.ClaimedIdentifierForOPIdentifier).CacheGeneratedResults(); var claimedIdentifiers = results.Where(result => result.ClaimedIdentifier != result.Protocol.ClaimedIdentifierForOPIdentifier); serviceEndpoints = opIdentifiers.Any() ? opIdentifiers : claimedIdentifiers; } catch (ProtocolException ex) { Logger.Yadis.ErrorFormat("Error while performing discovery on: \"{0}\": {1}", userSuppliedIdentifier, ex); serviceEndpoints = Enumerable.Empty <IdentifierDiscoveryResult>(); } // Filter disallowed endpoints. serviceEndpoints = relyingParty.SecuritySettings.FilterEndpoints(serviceEndpoints); // Call another method that defers request generation. return(await CreateInternalAsync(userSuppliedIdentifier, relyingParty, realm, returnToUrl, serviceEndpoints, createNewAssociationsAsNeeded, cancellationToken)); }
/// <summary> /// Creates an instance of <see cref="AuthenticationRequest"/> FOR TESTING PURPOSES ONLY. /// </summary> /// <param name="discoveryResult">The discovery result.</param> /// <param name="realm">The realm.</param> /// <param name="returnTo">The return to.</param> /// <param name="rp">The relying party.</param> /// <returns>The instantiated <see cref="AuthenticationRequest"/>.</returns> internal static AuthenticationRequest CreateForTest(IdentifierDiscoveryResult discoveryResult, Realm realm, Uri returnTo, OpenIdRelyingParty rp) { return(new AuthenticationRequest(discoveryResult, realm, returnTo, rp)); }
/// <summary> /// Performs deferred request generation for the <see cref="CreateAsync" /> method. /// </summary> /// <param name="userSuppliedIdentifier">The user supplied identifier.</param> /// <param name="relyingParty">The relying party.</param> /// <param name="realm">The realm.</param> /// <param name="returnToUrl">The return_to base URL.</param> /// <param name="serviceEndpoints">The discovered service endpoints on the Claimed Identifier.</param> /// <param name="createNewAssociationsAsNeeded">if set to <c>true</c>, associations that do not exist between this Relying Party and the asserting Providers are created before the authentication request is created.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// A sequence of authentication requests, any of which constitutes a valid identity assertion on the Claimed Identifier. /// Never null, but may be empty. /// </returns> /// <remarks> /// All data validation and cleansing steps must have ALREADY taken place /// before calling this method. /// </remarks> private static async Task <IEnumerable <AuthenticationRequest> > CreateInternalAsync(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable <IdentifierDiscoveryResult> serviceEndpoints, bool createNewAssociationsAsNeeded, CancellationToken cancellationToken) { Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); Requires.NotNull(relyingParty, "relyingParty"); Requires.NotNull(realm, "realm"); Requires.NotNull(serviceEndpoints, "serviceEndpoints"); //// // If shared associations are required, then we had better have an association store. ErrorUtilities.VerifyOperation(!relyingParty.SecuritySettings.RequireAssociation || relyingParty.AssociationManager.HasAssociationStore, OpenIdStrings.AssociationStoreRequired); Logger.Yadis.InfoFormat("Performing discovery on user-supplied identifier: {0}", userSuppliedIdentifier); IEnumerable <IdentifierDiscoveryResult> endpoints = FilterAndSortEndpoints(serviceEndpoints, relyingParty); var authRequestResults = endpoints.Select(async endpoint => { Logger.OpenId.DebugFormat("Creating authentication request for user supplied Identifier: {0}", userSuppliedIdentifier); // The strategy here is to prefer endpoints with whom we can create associations. if (relyingParty.AssociationManager.HasAssociationStore) { // In some scenarios (like the AJAX control wanting ALL auth requests possible), // we don't want to create associations with every Provider. But we'll use // associations where they are already formed from previous authentications. Association association = createNewAssociationsAsNeeded ? await relyingParty.AssociationManager.GetOrCreateAssociationAsync(endpoint, cancellationToken) : relyingParty.AssociationManager.GetExistingAssociation(endpoint); if (association == null && createNewAssociationsAsNeeded) { Logger.OpenId.WarnFormat("Failed to create association with {0}. Skipping to next endpoint.", endpoint.ProviderEndpoint); // No association could be created. Add it to the list of failed association // endpoints and skip to the next available endpoint. return(new KeyValuePair <IdentifierDiscoveryResult, AuthenticationRequest>(endpoint, null)); } } return(new KeyValuePair <IdentifierDiscoveryResult, AuthenticationRequest>(endpoint, new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty))); }).ToList(); await Task.WhenAll(authRequestResults); var results = (from pair in authRequestResults where pair.Result.Value != null select pair.Result.Value).ToList(); // Maintain a list of endpoints that we could not form an association with. // We'll fallback to generating requests to these if the ones we CAN create // an association with run out. var failedAssociationEndpoints = (from pair in authRequestResults where pair.Result.Value == null select pair.Result.Key).ToList(); // Now that we've run out of endpoints that respond to association requests, // since we apparently are still running, the caller must want another request. // We'll go ahead and generate the requests to OPs that may be down -- // unless associations are set as required in our security settings. if (failedAssociationEndpoints.Count > 0) { if (relyingParty.SecuritySettings.RequireAssociation) { Logger.OpenId.Warn("Associations could not be formed with some Providers. Security settings require shared associations for authentication requests so these will be skipped."); } else { Logger.OpenId.Debug("Now generating requests for Provider endpoints that failed initial association attempts."); foreach (var endpoint in failedAssociationEndpoints) { Logger.OpenId.DebugFormat("Creating authentication request for user supplied Identifier: {0} at endpoint: {1}", userSuppliedIdentifier, endpoint.ProviderEndpoint.AbsoluteUri); // Create the auth request, but prevent it from attempting to create an association // because we've already tried. Let's not have it waste time trying again. var authRequest = new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty); authRequest.associationPreference = AssociationPreference.IfAlreadyEstablished; results.Add(authRequest); } } } return(results); }
/// <summary> /// Returns a filtered and sorted list of the available OP endpoints for a discovered Identifier. /// </summary> /// <param name="endpoints">The endpoints.</param> /// <param name="relyingParty">The relying party.</param> /// <returns>A filtered and sorted list of endpoints; may be empty if the input was empty or the filter removed all endpoints.</returns> private static List <IdentifierDiscoveryResult> FilterAndSortEndpoints(IEnumerable <IdentifierDiscoveryResult> endpoints, OpenIdRelyingParty relyingParty) { Requires.NotNull(endpoints, "endpoints"); Requires.NotNull(relyingParty, "relyingParty"); bool anyFilteredOut = false; var filteredEndpoints = new List <IdentifierDiscoveryResult>(); foreach (var endpoint in endpoints) { if (relyingParty.FilterEndpoint(endpoint)) { filteredEndpoints.Add(endpoint); } else { anyFilteredOut = true; } } // Sort endpoints so that the first one in the list is the most preferred one. filteredEndpoints.OrderBy(ep => ep, relyingParty.EndpointOrder); var endpointList = new List <IdentifierDiscoveryResult>(filteredEndpoints.Count); foreach (var endpoint in filteredEndpoints) { endpointList.Add(endpoint); } if (anyFilteredOut) { Logger.Yadis.DebugFormat("Some endpoints were filtered out. Total endpoints remaining: {0}", filteredEndpoints.Count); } if (Logger.Yadis.IsDebugEnabled) { if (MessagingUtilities.AreEquivalent(endpoints, endpointList)) { Logger.Yadis.Debug("Filtering and sorting of endpoints did not affect the list."); } else { Logger.Yadis.Debug("After filtering and sorting service endpoints, this is the new prioritized list:"); Logger.Yadis.Debug(Util.ToStringDeferred(filteredEndpoints, true)); } } return(endpointList); }