我通过 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)