簡體   English   中英

從C#HttpClient對Spring服務器JWT令牌進行身份驗證

[英]Authentication from C# HttpClient against Spring server JWT Tokens

我正在編寫Xamarin跨平台移動應用程序。 該服務器是一台SpringMVC服務器,它使用JWT令牌針對每個端點/ Web服務進行身份驗證。 因此,基本上,當我第一次向Web服務發出請求時,在需要點擊/authorize POST端點發送我的電子郵件和密碼之前,端點響應將在"Cookie"標頭中包含一個身份驗證令牌,該令牌為"AUTH_TOKEN={MD5-String}" 一旦獲得令牌,就將請求發送到端點,比如說/feed 但是我的問題是我無法弄清楚在C# HttpClient中設置“ Cookie”標頭的方式。 我嘗試了所有方法,但是endpoing只是繼續使用登錄屏幕html而不是實際的JSON響應進行響應。 我在Postman和其他REST客戶端中嘗試了相同的步驟,並且有效。 所以這意味着我做錯了。 這是我的代碼:

public class RestService : IRestService
{
    HttpClient client;
    HttpClientHandler handler;
    CookieContainer cookies;
    string authToken;

    public List<Feed> FeedItems { get; private set; }

    public RestService()
    {
        cookies = new CookieContainer();
        handler = new HttpClientHandler();
        handler.UseCookies = true; //Otherwise It'll not use the cookies container!!
        handler.CookieContainer = cookies;
        client = new HttpClient(handler);
        client.MaxResponseContentBufferSize = 256000;
    }

    public async Task<List<Role>> GetFeedDataAsync()
    {
        //Request credentials
        //Credentials validation
        var credentials = new HalliganCredential()
        {
            email = Constants.Username,
            password = Constants.Password
        };
        var jsonCredentials = JsonConvert.SerializeObject(credentials);
        var jsonCredentialsContent = new StringContent(jsonCredentials, Encoding.UTF8, "application/json");
        var authorizeUri = new Uri(Constants.AuthorizeEndpoint);
        var authorizeResponse = await client.PostAsync(authorizeUri, jsonCredentialsContent);
        if (authorizeResponse.IsSuccessStatusCode)
        {
            //If authentication went OK
            IEnumerable<Cookie> responseCookies = cookies.GetCookies(authorizeUri).Cast<Cookie>();
            foreach (Cookie cookie in responseCookies)
            {
                if (cookie.Name.Equals("AUTH-TOKEN"))
                {
                    authToken = cookie.Value;
                }
            }
        }
        else
        {
            //Authentication failed throw error
            throw new HttpRequestException("Authentication failed");
        }


        FeedItems = new List<Feed>();

        //Making the GET request
        var uri = new Uri(string.Format(Constants.FeedEnpoint, string.Empty));
        try
        {
            cookies.Add(uri, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
            client.DefaultRequestHeaders.Add("Cookie", string.Format("AUTH_TOKEN={0}", authToken));
            handler.CookieContainer.Add(uri, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));

            var response = await client.GetAsync(uri);
            response.EnsureSuccessStatusCode();
            //Credentials validation
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                FeedItems = JsonConvert.DeserializeObject<List<Feed>>(content);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(@"ERROR {0}", ex.Message);
        }


        return FeedItems;
    }
}

當我到達那行時, var content = await response.Content.ReadAsStringAsync(); 響應是一個HTML字符串,而不是實際的JSON響應。

盡管"Cookie"是用於Postman的那個,但我嘗試使用其他幾個頭的鍵值。

我嘗試使用"Set-Cookie""set-cookie""Set-Cookie" ,將標題設置為"AUTH_TOKEN" 我在不同的地方嘗試了所有這些說服力,例如將它們添加到cookie CookieContainerhandler CookieContainerclient.DefaultRequestHeaders

我嘗試打開和關閉處理程序handler.UseCookies = true; //Otherwise It'll not use the cookies container!! handler.UseCookies = true; //Otherwise It'll not use the cookies container!! 線。

任何幫助都將受到歡迎!

更新

我嘗試了一種建議的解決方案,但沒有用,無論是對還是錯,我都對UseCookies進行了嘗試。

         //Making the GET request
        var baseAddress = new Uri("http://app.******.io");
        using (var handler = new HttpClientHandler { UseCookies = true })
        using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
        {
            var message = new HttpRequestMessage(HttpMethod.Get, "/api/v1/feed?api_key=sarasa");
            message.Headers.Add("Cookie", string.Format("AUTH_TOKEN={0}", authToken));
            message.Headers.Add("Cookie", string.Format("AUTH_TOKEN={0};", authToken));
            message.Headers.Add("Set-Cookie", string.Format("AUTH_TOKEN={0}", authToken));
            message.Headers.Add("AUTH_TOKEN", authToken);
            var result = await client.SendAsync(message);
            result.EnsureSuccessStatusCode();
            if (result.IsSuccessStatusCode)
            {
                var content = await result.Content.ReadAsStringAsync();
                FeedItems= JsonConvert.DeserializeObject<List<Feed>>(content);
            }
        }
        return FeedItems;

更新

我嘗試了另一種解決方案,結果相同。

var baseAddress = new Uri("http://app.*****.io");
            var cookieContainer = new CookieContainer();
            using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
            using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
            {
                cookieContainer.Add(baseAddress, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
                cookieContainer.Add(baseAddress, new Cookie("Set-Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
                var result = client.GetAsync("/api/v1/roles?api_key=sarasa").Result;
                result.EnsureSuccessStatusCode();
                if (result.IsSuccessStatusCode)
                {
                    var content = await result.Content.ReadAsStringAsync();
                    RolesItems = JsonConvert.DeserializeObject<List<Role>>(content);
                }
            }

HttpClient是否有替代方法?

我終於可以設置Cookie標頭參數,但是我通過HttpWebRequest更改HttpClient

獲取餅干

//Credentials validation
            var credentials = new CompanyCredential()
            {
                Email = Constants.Username,
                Password = Constants.Password
            };
            var jsonCredentials = JsonConvert.SerializeObject(credentials);
            var request = (HttpWebRequest) WebRequest.Create(new Uri(baseAddress, Constants.AuthorizeEndpoint));
            request.ContentType = "application/json";
            request.Method = "POST";
            var requestStream = request.GetRequestStreamAsync().Result;
            var streamWriter = new StreamWriter(requestStream);
            streamWriter.Write(jsonCredentials);
            streamWriter.Flush();
            try
            {
                HttpWebResponse response = (HttpWebResponse) request.GetResponseAsync().Result;
                if (response.StatusCode.Equals(HttpStatusCode.OK))
                {
                    authToken = response.Headers["Set-Cookie"];
                    tokenExpireDate = DateTime.ParseExact(response.Headers["Expires"], "yyyy-MM-dd HH:mm:ss,fff",
                                       System.Globalization.CultureInfo.InvariantCulture);
                }
                else
                {
                    //Authentication failed throw error
                    throw new HttpRequestException("Authentication failed");
                }
            } catch (Exception e)
            {
                Debug.WriteLine(string.Format("Warning: {0}", e.Message));
            }

設置餅干

var request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress, endpoint));
            SetHeaders(request);
            if (string.IsNullOrEmpty(authToken))
            {
                throw new AuthTokenNullException();
            }
            request.Headers["Cookie"] = authToken;
            request.Method = "GET";
            HttpWebResponse response = request.GetResponseAsync().Result as HttpWebResponse;
            if (!response.StatusCode.Equals(HttpStatusCode.OK))
            {
                throw new HttpRequestException(string.Format("Warning expected response as 200 and got {0}", Convert.ToString(response.StatusCode)));
            }
            var reader = new StreamReader(response.GetResponseStream());
            string stringResponse = reader.ReadToEnd();
            return JsonConvert.DeserializeObject<T>(stringResponse);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM