1

我通过 NuGet 使用 DotNetOpenAuth 4.3.0.0 版。

我使用以下教程开发了一个服务提供者。 https://github.com/DotNetOpenAuth/DotNetOpenAuth/wiki/Security-scenarios

在开发了一个示例服务提供者之后,我用 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);

我的 AuthServerHostImpl.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 bad request。_ ”之后的行处失败。堆栈跟踪如下所示。

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)
4

1 回答 1

2

您对“代码”令牌的第一个请求应使用 GET 请求进行。“访问令牌”的后续请求应使用 POST 请求进行。根据堆栈跟踪错误,您对访问令牌的请求似乎是 GET 请求,请尝试发布请求,即

$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);

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

祝你好运

于 2013-09-13T20:06:01.883 回答