public void Verify(IHttpContext context, JObject authToken, out ApiUser user)
        {
            SteamApiUser steamUser = authToken.ToObject <SteamApiUser>();

            if (steamUser == null)
            {
                throw new ForbiddenException();
            }

            user = steamUser;

            ApiUser.VerifyUser(steamUser, context);

            var allowedSteamIds = Config.Instance.SteamAuthentication.AllowedSteamIds;

            if (allowedSteamIds.Length > 0 && !allowedSteamIds.Contains(steamUser.SteamID))
            {
                Logging.Log(
                    new Dictionary <string, string>()
                {
                    { "SteamID", steamUser.SteamID }
                },
                    "JWT login request contained a SteamID not in the allow list."
                    );
                throw new ForbiddenException();
            }
        }
        public static SteamApiUser MakeSteamUser(IHttpContext context, ulong steamId)
        {
            var user = new SteamApiUser
            {
                SteamID = steamId.ToString()
            };

            ApiUser.InitializeUser(user, context);
            return(user);
        }
        public async Task <ApiUser> TryAuthenticate(IHttpContext context)
        {
            if (!Config.Instance.SteamAuthentication.Enabled)
            {
                throw new NotFoundException();
            }

            if (context.Request.Method != "GET")
            {
                // openid requests use GET
                throw new MethodNotAllowedException();
            }

            var queryString = context.Request.QueryString;

            if (queryString.Count == 0)
            {
                // Redirect to steam's openid endpoint
                var queryParams = new Dictionary <string, string>()
                {
                    { "openid.ns", "http://specs.openid.net/auth/2.0" },
                    { "openid.mode", "checkid_setup" },
                    // Normally, we would have the response come back to us, but we are using jwt and not session data.
                    //  This means the client has to make the call to us, not steam, as the client will need to receive the
                    //  resulting authorization header.
                    // These are left blank, and the client must fill them in on its own.
                    //{"openid.return_to", string.Format("{0}://{1}:{2}/login", Config.Protocol, Server.IP, Config.Port)},
                    //{"openid.realm", string.Format("{0}://{1}:{2}", Config.Protocol, Server.IP, Config.Port)},
                    { "openid.identity", "http://specs.openid.net/auth/2.0/identifier_select" },
                    { "openid.claimed_id", "http://specs.openid.net/auth/2.0/identifier_select" }
                };
                var query = GenerateQuery(queryParams);

                // Would be nice to use TemporarilyMoved here, but thats auto handled by browsers
                //  and there is no way for the client to receive the location being redirected.
                // context.Response.Headers.Add("Location", string.Format("{0}?{1}", ProviderUri, query));
                await context.SendResponse(Ceen.HttpStatusCode.OK, new AuthenticateWithSteamPayload()
                {
                    location = string.Format("{0}?{1}", ProviderUri, query)
                });

                return(null);
            }

            queryString["openid.mode"] = "check_authentication";

            var responseString = HttpPost(ProviderUri, GenerateQuery(queryString));

            var   match   = SteamIdRegex.Match(queryString["openid.claimed_id"]);
            ulong steamId = ulong.Parse(match.Groups[1].Value);

            match = IsValidRegex.Match(responseString);
            var isValid = match.Success;

            if (!isValid)
            {
                Logging.Log(
                    new Dictionary <string, string>()
                {
                    { "SteamID", steamId.ToString() }
                },
                    "Steam rejected the provided openid credentials."
                    );
                throw new ForbiddenException("Invalid Credentials.");
            }

            var allowedSteamIds = Config.Instance.SteamAuthentication.AllowedSteamIds;

            if (allowedSteamIds.Length > 0 && !allowedSteamIds.Contains(steamId.ToString()))
            {
                Logging.Log(
                    new Dictionary <string, string>()
                {
                    { "SteamID", steamId.ToString() }
                },
                    "Attempted login by a SteamID not in the allow list."
                    );
                throw new ForbiddenException();
            }

            var user = SteamApiUser.MakeSteamUser(context, steamId);

            Authenticator.SetUserToken(context, user);
            return(user);
        }