如何制作针对 ASP.NET WebAPI 进行身份验证的客户端?

Posted

技术标签:

【中文标题】如何制作针对 ASP.NET WebAPI 进行身份验证的客户端?【英文标题】:How to make a client which authenticates against ASP.NET WebAPI? 【发布时间】:2017-04-25 05:57:51 【问题描述】:

enter image description here我在 ASP.NET 中创建了 REST API,并使用http://server/token 作为 URL。

标题有

content-type: application/x-www-form-urlencode

body有grant_type作为密码,用户名和密码会得到带有token的json数据。

为了进一步的数据访问令牌,可以使用上述方法与邮递员一起使用

我需要在 android Studio 或 Xamarin 中实现一个客户端。

因为邮递员中的网址是“example.com/token”; ,然后在内容类型的标题键值中为 ("Content-Type:application/x-www-form-urlencoded) 和在正文键值对中为 (grant_type:password, username:email,password:pass) 和发送后响应采用 json 格式如下 "access_token": "token", "token_type": "bearer", "expires_in": 1209599, "userName": "mail@gmail.com", ".issued": "Fri , 2016 年 12 月 9 日 19:19:18 GMT”,“.expires”:“周五,2016 年 12 月 23 日 19:19:18 GMT” 这同样需要在 android 中完成

【问题讨论】:

您能否更清楚地解释您的请求是如何提出的?令牌是否设置了标头或参数,或者可能是请求的主体?邮递员的一个例子将有助于理解您的问题。 因为邮递员中的 url 是 "example.com/token" ,然后在 Header Key value pais for content type as ("Content-Type:application/x-www-form-urlencoded) 和 body key value配对为 (grant_type:password, username:email,password:pass),发送后响应为 json 格式,如下 "access_token": "token", "token_type": "bearer", "expires_in": 1209599, "用户名”:“mail@gmail.com”,“.issued”:“格林威治标准时间 2016 年 12 月 9 日星期五 19:19:18”,“.expires”:“格林威治标准时间 2016 年 12 月 23 日星期五 19:19:18” 我需要在 android 中做同样的事情 请用您在 cmets 中写的内容更新问题正文,这会让其他人更容易阅读 我想你可以试试我的答案***.com/questions/32696960/… 【参考方案1】:

在您的依赖项中包含 System.Net.Http(需要 Xamarin 配置文件 111),然后您可以使用它创建一个 HttpClient 并通过 HTTP POST(类似于您在 Postman 中所做的)请求令牌,如下所示..

_client = new HttpClient();

var uri = new Uri("http://server/token");
var content = new FormUrlEncodedContent(
        new List<KeyValuePair<string, string>> 
            new KeyValuePair<string, string>("username", _username),
            new KeyValuePair<string, string>("password", _password),
            new KeyValuePair<string, string>("grant_type", "password")
        );
HttpResponseMessage response = await _client.PostAsync(uri, content);

其中 _username 和 _password 是字符串。

然后通过将响应转换为字典或任何其他合理的替代方法来解析 JSON 响应来读取响应。

if (response.StatusCode == HttpStatusCode.OK) 
        var jsonContent = await response.Content.ReadAsStringAsync();
        var responseDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonContent);
        if (responseDict.ContainsKey("access_token"))
            _token = responseDict["access_token"];

然后,一旦您拥有令牌,您就可以将其作为该 HttpClient 实例中所有标头的默认授权值包含在内!

_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);

其中 _token 是令牌,因为它是编码字符串,例如"eyJ0eXAiOiJKV1QiLC..."

刚刚实现了这个并验证了它的正确性 - 我在一个生产环境中运行它,我已经设置了使用 JWT 进行验证,它很有效。

【讨论】:

【参考方案2】:

这行得通,它看起来很丑,但你可以改变它

    var authCredentials = "grant_type=password&username=" + WebUtility.UrlEncode(LoginBindingModel.Email) + "&password=" + LoginBindingModel.Password;
    string response = await Client.MakePostFormRequest("token", authCredentials);


public static async Task<string> MakePostFormRequest(string url, string data)
    
        try
        
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(BaseUrl + "token");
            // Set the Method property of the request to POST.
            request.Accept = "*/*";
            request.Method = "POST";

            // Create POST data and convert it to a byte array.
            byte[] byteArray = Encoding.UTF8.GetBytes(data);
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            // Set the ContentLength property of the WebRequest.
            //request.ContentLength = byteArray.Length;
            // Get the request stream.
            Stream dataStream = await request.GetRequestStreamAsync().ConfigureAwait(false);
            // Write the data to the request stream.
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.
            dataStream.Dispose();
            // Get the response.
            WebResponse response = await request.GetResponseAsync().ConfigureAwait(false);
            // Display the status.
            //Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.

            string responseFromServer = reader.ReadToEnd();
            // Display the content.
            //Console.WriteLine(responseFromServer);
            // Clean up the streams.
            TokenViewModel TokenViewModel = JsonConvert.DeserializeObject<TokenViewModel >(responseFromServer);
            VariablesGlobales.Token = TokenViewModel.access_token;
            VariablesGlobales.LoginStamp = TokenViewModel.LoginStamp;
            reader.Dispose();
            dataStream.Dispose();
            response.Dispose();

            return responseFromServer;
        
        catch (Exception ex)
        
            return "";
        
    

当你想要验证你的请求时

public static async Task<string> MakePostRequest(string url, string data)
    
        var result = "";
        try
        
            var httpWebRequest = (HttpWebRequest)WebRequest.Create(BaseUrl + url);
            httpWebRequest.ContentType = "application/json; charset=utf-8";
            httpWebRequest.Method = "POST";
            if (VariablesGlobales.Token != "")
            
                httpWebRequest.Headers[HttpRequestHeader.Authorization] = "Bearer " + VariablesGlobales.Token;
            

            using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)))
            
                streamWriter.Write(data);
                streamWriter.Flush();
            

            var httpResponse = (HttpWebResponse)(await httpWebRequest.GetResponseAsync().ConfigureAwait(false));

            if (httpResponse.StatusCode.ToString() == "OK")
            
                result = httpResponse.StatusCode.ToString();
            
            else
            
                result = "";
            

        

        catch (Exception ex)
        
            result = "";
        
        return result;
    

【讨论】:

在 android studio m 中工作无法解析 HttpWebRequest 的符号,如果您不介意提供更多帮助,我需要将这些方法作为其给出的错误很多地方放置 抱歉,这是针对 C# 中的 Xamarin.Android 的,我建议您删除该标签

以上是关于如何制作针对 ASP.NET WebAPI 进行身份验证的客户端?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何保护我的 Web 应用程序(ASP.Net Core 3.1 MVC)?

选择 webApi 模板时如何将 ASP.Net 身份添加到 Asp.Net Core?

asp.net 如何变成 MVC 或 WebApi?

asp.net WebApi 使用总结

ASP.NET Core 2.2 WebAPI 405 方法不允许

ASP .NET MVC 4 WebApi:手动处理 OData 查询