public async Task <SteamOpenIdState> LinkWithSteamTaskAsync(ulong discordUserId) { var a = Guid.NewGuid(); var state = new SteamOpenIdState { ReturnTo = new Uri(new Uri(_options.RedirectUri), $"?a={a}"), Identity = @"http://specs.openid.net/auth/2.0/identifier_select", ClaimedId = @"http://specs.openid.net/auth/2.0/identifier_select", Authority = _authority, DiscordUserId = discordUserId, }; if (!_states.TryAdd(a, state)) { return(null); } //&openid.realm={state.Realm} var uri = new Uri(new Uri(await _endpoint), $@"?openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup&openid.return_to={state.ReturnTo}&openid.claimed_id={state.ClaimedId}&openid.identity={state.Identity}"); state.StartUrl = uri.ToString(); return(state); }
private async Task HandleRequestAsync(HttpListenerContext context) { var successful = false; ulong steamId = 0; SteamOpenIdState state = null; try { var request = context.Request; var qs = request.QueryString; Guid a; if (!Guid.TryParse(qs["a"] ?? "", out a)) { //request failed return; } if (!_states.TryRemove(a, out state)) { //failed to get state return; } var query = UriExtensions.ParseQueryString(state.ReturnTo); if (request.Url.Scheme != state.ReturnTo.Scheme || request.Url.Authority != state.ReturnTo.Authority || request.Url.AbsolutePath != state.ReturnTo.AbsolutePath || query.AllKeys.Any(x => qs[x] == null || qs[x].Equals(query[x], StringComparison.Ordinal) == false) || qs["openid.mode"]?.Equals("id_res") != true || qs["openid.claimed_id"]?.StartsWith(state.Authority) != true) { //assertions failed return; } var r = new Regex(@"/openid/id/(?<steamid>\d+)$", RegexOptions.IgnoreCase | RegexOptions.Singleline); var m = r.Match(qs["openid.claimed_id"]); if (!m.Success) { //failed to get steamid return; } if (!ulong.TryParse(m.Groups["steamid"].Value, NumberStyles.None, CultureInfo.InvariantCulture, out steamId)) { return; } successful = true; //openid/ //?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0 //&openid.mode=id_res //&openid.op_endpoint=https%3A%2F%2Fsteamcommunity.com%2Fopenid%2Flogin //&openid.claimed_id=http%3A%2F%2Fsteamcommunity.com%2Fopenid%2Fid%2F76561198005371608 //&openid.identity=http%3A%2F%2Fsteamcommunity.com%2Fopenid%2Fid%2F76561198005371608 //&openid.return_to=http%3A%2F%2F62.63.229.45%3A7331%2Fopenid%2F //&openid.response_nonce=2017-02-05T18%3A20%3A46ZwFvmnCumgCkT9IWOoIDpaJLc6%2Bs%3D //&openid.assoc_handle=1234567890 //&openid.signed=signed%2Cop_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle //&openid.sig=Cpo83xgHcMqzVOyQqe693s%2FRQO4%3D } finally { Task task; _ongoingTasks.TryRemove(context.Request.RequestTraceIdentifier, out task); if (state != null) { OnSteamOpenIdCallback(successful, steamId, state.DiscordUserId); if (_getHtmlContent != null) { var content = await _getHtmlContent(successful, steamId, state.DiscordUserId); var buffer = Encoding.UTF8.GetBytes(content); context.Response.ContentLength64 = buffer.Length; await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length); context.Response.OutputStream.Close(); } } } }