我有一个示例应用程序可以在客户端使用 IdentityServer v3 和 OpenID Connect 授权代码流进行授权。我可以成功获取authorization_code
andsession_state
但是当我调用令牌端点时出现问题。令牌端点响应Invalid HTTP status code 405
这是 Angular.js 配置的代码。
Angular.js
应用程序.js
angular.module('oidc3', ['oauth', 'ngStorage', 'base64'])
.config(function ($locationProvider, $httpProvider) {
$locationProvider.html5Mode(true);
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.useXDomain = false;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
});
登录控制器
angular.module('oidc3')
.controller('LoginController', function ($scope, $http, $timeout, $location, $base64) {
var getParamsFromUrl = function(url) {
var splitted = url.split('?');
splitted = splitted[1].split('&');
var params = {};
for (var i = 0; i < splitted.length; i++) {
var param = splitted[i].split('=');
var key = param[0];
var value = param[1];
params[key] = value
}
return params;
};
var getToken = function (url, data, header) {
$http.defaults.headers.common.Authorization = header;
return $http.post(url, data);
};
if($location.absUrl().split('?')[1]) {
$scope.params = getParamsFromUrl($location.absUrl());
var tokenEndpoint = 'https://localhost:44333/connect/token';
var client_id = 'codeclient';
var client_secret = 'secret';
var str = client_id + ':' + client_secret;
var baseEncoded = $base64.encode(str);
var tokenData = {};
tokenData.grant_type = 'authorization_code';
tokenData.code = $scope.params.code;
tokenData.redirect_uri = 'http://localhost:8000/login.html';
var reqHeader = 'Basic ' + baseEncoded;
getToken(tokenEndpoint, tokenData, reqHeader)
.success(function (data, status, headers, config) {
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
}).error(function (data, status, headers, config) {
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
});
}
});
我手动将授权标头设置为Basic
编码client_id
和client_secret
. 当发送 POST 请求时,服务器返回 405 响应。Chrome 开发者工具网络部分的屏幕截图在这里。
但是,当我没有手动设置标头时,POST 请求会正确发送,并且服务器会返回invalid_client
错误,因为它无法在没有标头的情况下对客户端进行身份验证。IdentityServer v3 Trace.log 消息如下。
使用手动设置授权标头
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.WelcomeController]: 4/29/2015 3:34:19 AM +00:00 -- Welcome page requested
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.WelcomeController]: 4/29/2015 3:34:19 AM +00:00 -- Rendering welcome page
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:34:34 AM +00:00 -- Start authorize request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:34 AM +00:00 -- Start authorize request protocol validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:34 AM +00:00 -- Authorize request validation success
{
"RedirectUri": "http://localhost:8000/login.html",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278473164",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278473164",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:34 AM +00:00 -- Start authorize request client validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:34 AM +00:00 -- Authorize request validation success
{
"ClientId": "codeclient",
"ClientName": "Code Flow Client Demo",
"RedirectUri": "http://localhost:8000/login.html",
"AllowedRedirectUris": [
"https://localhost:44312/callback",
"http://localhost:63342/oidc_test/redirect.html",
"http://localhost:8000/login.html",
"https://localhost:4443/login.html"
],
"SubjectId": "88421113",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278473164",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278473164",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:34:34 AM +00:00 -- Showing consent screen
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:34:34 AM +00:00 -- End authorize request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:34:36 AM +00:00 -- Resuming from consent, restarting validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:36 AM +00:00 -- Start authorize request protocol validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:36 AM +00:00 -- Authorize request validation success
{
"RedirectUri": "http://localhost:8000/login.html",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278473164",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278473164",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:36 AM +00:00 -- Start authorize request client validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:34:36 AM +00:00 -- Authorize request validation success
{
"ClientId": "codeclient",
"ClientName": "Code Flow Client Demo",
"RedirectUri": "http://localhost:8000/login.html",
"AllowedRedirectUris": [
"https://localhost:44312/callback",
"http://localhost:63342/oidc_test/redirect.html",
"http://localhost:8000/login.html",
"https://localhost:4443/login.html"
],
"SubjectId": "88421113",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278473164",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278473164",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.AuthorizeResponseGenerator]: 4/29/2015 3:34:36 AM +00:00 -- Creating Authorization Code Flow response.
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.AuthorizeRedirectResult]: 4/29/2015 3:34:36 AM +00:00 -- Redirecting to: http://localhost:8000/login.html
无需手动设置授权标头
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.WelcomeController]: 4/29/2015 3:37:39 AM +00:00 -- Welcome page requested
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.WelcomeController]: 4/29/2015 3:37:39 AM +00:00 -- Rendering welcome page
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:37:52 AM +00:00 -- Start authorize request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:52 AM +00:00 -- Start authorize request protocol validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:52 AM +00:00 -- Authorize request validation success
{
"RedirectUri": "http://localhost:8000/login.html",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278670509",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278670509",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:52 AM +00:00 -- Start authorize request client validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:52 AM +00:00 -- Authorize request validation success
{
"ClientId": "codeclient",
"ClientName": "Code Flow Client Demo",
"RedirectUri": "http://localhost:8000/login.html",
"AllowedRedirectUris": [
"https://localhost:44312/callback",
"http://localhost:63342/oidc_test/redirect.html",
"http://localhost:8000/login.html",
"https://localhost:4443/login.html"
],
"SubjectId": "88421113",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278670509",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278670509",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:37:52 AM +00:00 -- Showing consent screen
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:37:52 AM +00:00 -- End authorize request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthorizeEndpointController]: 4/29/2015 3:37:54 AM +00:00 -- Resuming from consent, restarting validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:54 AM +00:00 -- Start authorize request protocol validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:54 AM +00:00 -- Authorize request validation success
{
"RedirectUri": "http://localhost:8000/login.html",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278670509",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278670509",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:54 AM +00:00 -- Start authorize request client validation
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.AuthorizeRequestValidator]: 4/29/2015 3:37:54 AM +00:00 -- Authorize request validation success
{
"ClientId": "codeclient",
"ClientName": "Code Flow Client Demo",
"RedirectUri": "http://localhost:8000/login.html",
"AllowedRedirectUris": [
"https://localhost:44312/callback",
"http://localhost:63342/oidc_test/redirect.html",
"http://localhost:8000/login.html",
"https://localhost:4443/login.html"
],
"SubjectId": "88421113",
"ResponseType": "code",
"ResponseMode": "query",
"Flow": "AuthorizationCode",
"RequestedScopes": "openid profile email",
"State": "1430278670509",
"Nonce": "nonce",
"SessionId": "585c26034281e898b73012e9335868cb",
"Raw": {
"response_type": "code",
"client_id": "codeclient",
"redirect_uri": "http://localhost:8000/login.html",
"scope": "openid profile email",
"state": "1430278670509",
"nonce": "nonce"
}
}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.AuthorizeResponseGenerator]: 4/29/2015 3:37:54 AM +00:00 -- Creating Authorization Code Flow response.
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.AuthorizeRedirectResult]: 4/29/2015 3:37:54 AM +00:00 -- Redirecting to: http://localhost:8000/login.html
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 4/29/2015 3:37:55 AM +00:00 -- Start token request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.ClientValidator]: 4/29/2015 3:37:55 AM +00:00 -- Start client validation
iisexpress.exe Error: 0 : [Thinktecture.IdentityServer.Core.Validation.ClientValidator]: 4/29/2015 3:37:55 AM +00:00 -- No or malformed client credential found.
{}
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 4/29/2015 3:37:55 AM +00:00 -- End token request
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.TokenErrorResult]: 4/29/2015 3:37:55 AM +00:00 -- Returning error: invalid_client
我做了一些研究,发现这与 CORS 有关,这是由于预检检查我的客户是否可以访问我正在调用的端点。我怎样才能避免这种情况并将 POST 请求按原样发送到令牌端点。