如果数据是对象,则 OWIN 授权失败
OWIN Authorization fails if data is an object
这怎么行得通:
var data = "grant_type=password&client_id="
+ appSettings.authClientId
+ "&username="
+ loginData.userName
+ "&password="
+ loginData.password;
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/json" } }
)
但这会产生 400 错误:clientId 为空:
var data = {
grant_type: "password",
client_id: appSettings.authClientId,
username: loginData.userName,
password: loginData.password
};
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/json" } }
)
这是服务器端的代码:
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
OAuth 2.0 的 specification 要求您在 body 中发送参数:
HEADER:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
BODY:
grant_type=password&username=johndoe&password=A3ddj3w
事实上,即使您更改 Content-Type (header):
,您的第一个请求也应该有效
var data = "grant_type=password&client_id="
+ appSettings.authClientId
+ "&username="
+ loginData.userName
+ "&password="
+ loginData.password;
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } }
)
在您的第二个示例代码中,您的请求在 body 中,格式如下:
{"grant_type":"密码","用户名":"我的用户名","密码":"我的密码"}
而您的 ValidateClientAuthentication
无法解析它。
您可以使用 transformRequest 尝试另一种方法:
$http({
method: 'POST',
url: appSettings.apiServiceBaseUri + "token",
headers: { 'Authorization': 'Basic ' + authorizationBasic },
data: { username: loginData.userName, password: loginData.password, grant_type: 'password' },
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
}).success(function (data, status, headers, config) {
// deferred.resolve(data);
}).error(function (data, status, headers, config) {
// deferred.reject("An error occured while fetching items");
});
这怎么行得通:
var data = "grant_type=password&client_id="
+ appSettings.authClientId
+ "&username="
+ loginData.userName
+ "&password="
+ loginData.password;
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/json" } }
)
但这会产生 400 错误:clientId 为空:
var data = {
grant_type: "password",
client_id: appSettings.authClientId,
username: loginData.userName,
password: loginData.password
};
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/json" } }
)
这是服务器端的代码:
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
OAuth 2.0 的 specification 要求您在 body 中发送参数:
HEADER:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
BODY:
grant_type=password&username=johndoe&password=A3ddj3w
事实上,即使您更改 Content-Type (header):
,您的第一个请求也应该有效var data = "grant_type=password&client_id="
+ appSettings.authClientId
+ "&username="
+ loginData.userName
+ "&password="
+ loginData.password;
$http.post(
appSettings.apiServiceBaseUri + "token",
data,
{ headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } }
)
在您的第二个示例代码中,您的请求在 body 中,格式如下:
{"grant_type":"密码","用户名":"我的用户名","密码":"我的密码"}
而您的 ValidateClientAuthentication
无法解析它。
您可以使用 transformRequest 尝试另一种方法:
$http({
method: 'POST',
url: appSettings.apiServiceBaseUri + "token",
headers: { 'Authorization': 'Basic ' + authorizationBasic },
data: { username: loginData.userName, password: loginData.password, grant_type: 'password' },
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
}).success(function (data, status, headers, config) {
// deferred.resolve(data);
}).error(function (data, status, headers, config) {
// deferred.reject("An error occured while fetching items");
});