通过PHP脚本在基于DotNetOpenAuth的提供商服务上使用OAuth 2.0时获得奇怪的异常和死亡

本文关键字:0时 异常 OAuth 脚本 PHP DotNetOpenAuth 通过 服务 提供商 | 更新日期: 2023-09-27 18:14:52

我通过NuGet使用DotNetOpenAuth 4.3.0.0版本。

我使用下面的教程开发了一个Service Provider。https://github.com/DotNetOpenAuth/DotNetOpenAuth/wiki/Security-scenarios

在开发了一个示例Service Provider之后,我用PHP开发了一个简单的网站,它使用OAuth。

<?php
$client_id = 'RP';
$client_secret = 'password';
$callback_url = 'http://localhost/dotnetoauthtester/index.php';
$service_provider_url = 'http://localhost:58883/OAuth/';
$code = $_REQUEST["code"];
if(empty($code)){
    $state = '';
    $scope = 'http://localhost/some_web_service/';
    $auth_url = $service_provider_url.'auth?'
        .'client_id='.$client_id
        .'&response_type=code'
        .'&redirect_uri='.$callback_url
        .'&state='.$state
        .'&scope='.$scope;
    header('Location:'.$auth_url);
    exit();
}
$access_token_url = $service_provider_url.'token?'
    .'client_id='.$client_id
    .'&client_secret='.$client_secret
    .'&redirect_uri='.$callback_url
    .'&code='.$code
    .'&grant_type=authorization_code';
# ___ It returns 400 bad request here. ___
$access_token_array = json_decode(file_get_contents($access_token_url),true);
var_dump($access_token_array);

我的authserverhostipls .cs是这样的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Web;
using DotNetOpenAuth.OAuth2;
using DotNetOpenAuth.OAuth2.ChannelElements;
using DotNetOpenAuth.OAuth2.Messages;
namespace ServiceProviderTestMvc.Models
{
    public class AuthServerHostImpl : IAuthorizationServerHost
    {
        public IClientDescription GetClient(string clientIdentifier)
        {
            switch (clientIdentifier)
            {
                case "RP":
                    var allowedCallback = "http://localhost/dotnetoauthtester/index.php";
                    return new ClientDescription("data!", new Uri(allowedCallback), ClientType.Confidential);
            }
            return null;
        }
        public bool IsAuthorizationValid(IAuthorizationDescription authorization)
        {
            if (authorization.ClientIdentifier == "RP"
                && authorization.Scope.Count == 1
                && authorization.Scope.First() == "http://localhost/some_web_service/"
                && authorization.User == "Max muster")
            {
                return true;
            }
            return false;
        }
        public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage)
        {
            var token = new AuthorizationServerAccessToken();
            token.Lifetime = TimeSpan.FromMinutes(10);
            var signCert = LoadCert(Config.STS_CERT);
            token.AccessTokenSigningKey = (RSACryptoServiceProvider)signCert.PrivateKey;
            var encryptCert = LoadCert(Config.SERVICE_CERT);
            token.ResourceServerEncryptionKey = (RSACryptoServiceProvider)encryptCert.PublicKey.Key;
            var result = new AccessTokenResult(token);
            return result;
        }
        private static X509Certificate2 LoadCert(string thumbprint)
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            var certs = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, validOnly: false);
            if (certs.Count == 0)
            {
                throw new Exception("Could not find certification!!");
            }
            var cert = certs[0];
            return cert;
        }
        public DotNetOpenAuth.Messaging.Bindings.ICryptoKeyStore CryptoKeyStore
        {
            get
            {
                return new InMemoryCryptoKeyStore();
            }
        }
        public DotNetOpenAuth.Messaging.Bindings.INonceStore NonceStore
        {
            get
            {
                return new DummyNonceStore();
            }
        }
        public AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest)
        {
            throw new NotImplementedException();
        }
        public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest)
        {
            throw new NotImplementedException();
        }
    }
}
但是,它在"_"之后的行失败了,它在这里返回400个错误请求。_ "。堆栈跟踪如下所示。
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,393 [33] DEBUG DotNetOpenAuth.Messaging [(null)] - The following required parameters were missing from the DotNetOpenAuth.OAuth2.AuthServer.Messages.AccessTokenRefreshRequestAS message: {refresh_token,
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,394 [33] DEBUG DotNetOpenAuth.Messaging [(null)] - The following required parameters were missing from the DotNetOpenAuth.OAuth2.Messages.AccessTokenResourceOwnerPasswordCredentialsRequest message: {username,
password,
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,394 [33] DEBUG DotNetOpenAuth.Messaging [(null)] - The following required parameters were missing from the DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationRequest message: {response_type,
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,395 [33] DEBUG DotNetOpenAuth.Messaging [(null)] - The following required parameters were missing from the DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationImplicitRequest message: {response_type,
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,395 [33] DEBUG DotNetOpenAuth.Messaging [(null)] - The following required parameters were missing from the DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationFailedResponse message: {error,
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,396 [33] WARN DotNetOpenAuth.Messaging [(null)] - Multiple message types seemed to fit the incoming data: {AccessTokenAuthorizationCodeRequestAS (2.0),
AccessTokenClientCredentialsRequest (2.0),
}
DotNetOpenAuth.Messaging: 2013-05-23 14:08:47,397 [33] ERROR DotNetOpenAuth.Messaging [(null)] - Protocol error: 'AccessTokenAuthorizationCodeRequestAS' messages cannot be received with HTTP verb 'GetRequest'.
at DotNetOpenAuth.Messaging.ErrorUtilities.VerifyProtocol(Boolean condition, String unformattedMessage, Object[] args)
at DotNetOpenAuth.Messaging.Channel.Receive(Dictionary2 fields, MessageReceivingEndpoint recipient)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequestCore(HttpRequestBase request)
at DotNetOpenAuth.OAuth2.ChannelElements.OAuth2AuthorizationServerChannel.ReadFromRequestCore(HttpRequestBase request)
at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestBase httpRequest)
at DotNetOpenAuth.Messaging.Channel.TryReadFromRequest[TRequest](HttpRequestBase httpRequest, TRequest& request)
at DotNetOpenAuth.OAuth2.AuthorizationServer.HandleTokenRequest(HttpRequestBase request)
at ServiceProviderTestMvc.Controllers.OAuthController.Token()
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass81.b__7(IAsyncResult )
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass25.<>c__DisplayClass2a.b__20()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__22(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)

通过PHP脚本在基于DotNetOpenAuth的提供商服务上使用OAuth 2.0时获得奇怪的异常和死亡

对"code"令牌的第一个请求应该使用GET请求。对"访问令牌"的后续请求应该使用POST请求进行。根据堆栈跟踪错误,看起来您对访问令牌的请求是GET请求,请尝试post该请求,即

$postdata = http_build_query(
array(
    'client_id' => $client_id,
    'client_secret' => $client_secret,
    'redirect_uri' => $callback_url,
    'code' => $code,
    'grant_type' => 'authorization_code'
));
$opts = array('http' =>
array(
    'method'  => 'POST',
    'header'  => 'Content-type: application/x-www-form-urlencoded',
    'content' => $postdata
));
$context  = stream_context_create($opts);
$result = file_get_contents($service_provider_url.'token', false, $context);

上面的代码只是一个建议,没有经过测试。

好运