programing

DotNetOpen과 함께 PLINTEXT 서명을 사용할 수 없습니다.인증 서비스 공급자

telebox 2023. 6. 16. 21:41
반응형

DotNetOpen과 함께 PLINTEXT 서명을 사용할 수 없습니다.인증 서비스 공급자

(NuGet 패키지)를 사용하여 인증 서버를 구축하고 있습니다.DotNetOpenAuth.OAuth.ServiceProvider, version = 4.1.4.12333서버가 ASP.NET 응용 프로그램에서 호스팅되지만 이는 질문과 관련이 없습니다.

의 구성은 다음과 같습니다.

private ServiceProvider GetServiceProvider()
{
    var baseUri = "http://myauth.com";
    return new ServiceProvider(
        new ServiceProviderDescription
        {
            UserAuthorizationEndpoint = new MessageReceivingEndpoint(
                new Uri(baseUri + "/get_request_token"), 
                HttpDeliveryMethods.GetRequest
            ),
            RequestTokenEndpoint = new MessageReceivingEndpoint(
                new Uri(baseUri + "/authorize"), 
                HttpDeliveryMethods.PostRequest
            ),
            AccessTokenEndpoint = new MessageReceivingEndpoint(
                new Uri(baseUri + "/get_token"), 
                HttpDeliveryMethods.PostRequest
            ),
            ProtocolVersion = ProtocolVersion.V10a,
            TamperProtectionElements = new ITamperProtectionChannelBindingElement[] 
            {
                new PlaintextSigningBindingElement(),
                new HmacSha1SigningBindingElement(),
            },
        },
        tokenManager,
        new OAuthServiceProviderMessageFactory(tokenManager)
    );
}

나의 관련된 부분.get_request_token엔드포인트는 다음과 같습니다.

var serviceProvider = GetServiceProvider();
var tokenRequest = serviceProvider.ReadTokenRequest();

이제 소비자가 이 엔드포인트로 다음과 같은 요청을 보낼 때:

GET /get_request_token?oauth_nonce=C5657420BCE5F3224914304376B5334696B09B7FFC17C105A7F9629A008869DC&oauth_timestamp=1356006599&oauth_consumer_key=sampleconsumer&oauth_signature_method=plaintext&oauth_signature=samplesecret%26&oauth_version=1.0&oauth_callback=http%3a%2f%2flocalhost%3a30103%2fCustomOAuth1 HTTP/1.1

Host: localhost:8180
Connection: close

(명확함을 위해 깨짐):

oauth_nonce=C5657420BCE5F3224914304376B5334696B09B7FFC17C105A7F9629A008869DC
oauth_timestamp=1356006599
oauth_consumer_key=sampleconsumer
oauth_signature_method=plaintext
oauth_signature=samplesecret%26
oauth_version=1.0
oauth_callback=http%3a%2f%2flocalhost%3a30103%2fCustomOAuth1

serviceProvider.ReadTokenRequest()메서드가 예외를 발생시킵니다.

The UnauthorizedTokenRequest message required protections {All} but the channel could only apply {Expiration, ReplayProtection}.
   at DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage message)
   at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestBase httpRequest)
   at DotNetOpenAuth.Messaging.Channel.TryReadFromRequest[TRequest](HttpRequestBase httpRequest, TRequest& request)
   at DotNetOpenAuth.OAuth.ServiceProvider.ReadTokenRequest(HttpRequestBase request)
   at DotNetOpenAuth.OAuth.ServiceProvider.ReadTokenRequest()
   at OAuthServers.OAuth1.Services.OAuth1Service.Any(GetRequestTokenRequest request)
   at lambda_method(Closure , Object , Object )
   at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request)

반면에 클라이언트가 다음과 같은 요청을 보내는 경우:

GET /get_request_token?oauth_callback=http%3a%2f%2flocalhost%3a65271%2foauth1%2fHandleAccessToken&oauth_consumer_key=sampleconsumer&oauth_nonce=rGFvxlWm&oauth_signature_method=HMAC-SHA1&oauth_signature=HV%2f5Vq%2b0cF3NrtiISE9k4jmgCrY%3d&oauth_version=1.0&oauth_timestamp=1356007830 HTTP/1.1

Host: localhost:8180
Connection: close

(명확함을 위해 깨짐):

oauth_callback=http%3a%2f%2flocalhost%3a65271%2foauth1%2fHandleAccessToken
oauth_consumer_key=sampleconsumer
oauth_nonce=rGFvxlWm
oauth_signature_method=HMAC-SHA1
oauth_signature=HV%2f5Vq%2b0cF3NrtiISE9k4jmgCrY%3d
oauth_version=1.0
oauth_timestamp=1356007830

성공합니다.

이 두 요청 간의 유일한 차이점은 다음과 같습니다.oauth_signature_method사용되고 있는첫 번째 경우PLAINTEXT사용되는 반면 두 번째에는 사용됩니다.HMAC-SHA1.

DotNet을 열 수 있습니까?인증 승인 aPLAINTEXTGET 동사와 함께 요청 토큰 엔드포인트에 대한 서명 방법(이 엔드포인트에 POST를 사용하도록 권장하는 경우에도 해당)?서버의 이러한 요구 사항을 완화할 수 있는 구성 옵션이 있습니까?

현재로서는 고객을 수정하는 것은 저에게 선택사항이 아닙니다.

OAuth 인증은 3단계로 수행됩니다.

  1. 소비자가 승인되지 않은 요청 토큰을 얻습니다.

  2. 사용자가 요청 토큰을 승인합니다.

  3. 소비자가 요청 토큰을 액세스 토큰으로 교환합니다.

그러면 다음과 같습니다.

public class InMemoryTokenManager : IConsumerTokenManager, IOpenIdOAuthTokenManager
{
private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>();

public InMemoryTokenManager(string consumerKey, string consumerSecret)
{
    if (String.IsNullOrEmpty(consumerKey))
    {
        throw new ArgumentNullException("consumerKey");
    }

    this.ConsumerKey = consumerKey;
    this.ConsumerSecret = consumerSecret;
}

public string ConsumerKey { get; private set; }

public string ConsumerSecret { get; private set; }

#region ITokenManager Members

public string GetConsumerSecret(string consumerKey)
{
    if (consumerKey == this.ConsumerKey)
    {
        return this.ConsumerSecret;
    }
    else
    {
        throw new ArgumentException("Unrecognized consumer key.", "consumerKey");
    }
}

public string GetTokenSecret(string token)
{
    return this.tokensAndSecrets[token];
}

public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response)
{
    this.tokensAndSecrets[response.Token] = response.TokenSecret;
}

public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret)
{
    this.tokensAndSecrets.Remove(requestToken);
    this.tokensAndSecrets[accessToken] = accessTokenSecret;
}

/// <summary>
/// Classifies a token as a request token or an access token.
/// </summary>
/// <param name="token">The token to classify.</param>
/// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
public TokenType GetTokenType(string token)
{
    throw new NotImplementedException();
}

#endregion

#region IOpenIdOAuthTokenManager Members

public void StoreOpenIdAuthorizedRequestToken(string consumerKey, AuthorizationApprovedResponse authorization)
{
    this.tokensAndSecrets[authorization.RequestToken] = string.Empty;
}

#endregion
}

다음 코드 블록은 일반 텍스트 서명을 생성하는 데 도움이 될 수 있습니다.

public static string GetSignature(OAuthSignatureMethod signatureMethod,             AuthSignatureTreatment signatureTreatment, string signatureBase, string consumerSecret, string tokenSecret)
{
    if (tokenSecret.IsNullOrBlank())
    {
        tokenSecret = String.Empty;
    }

    consumerSecret = UrlEncodeRelaxed(consumerSecret);
    tokenSecret = UrlEncodeRelaxed(tokenSecret);

    string signature;
    switch (signatureMethod)
    {
        case OAuthSignatureMethod.HmacSha1:
        {
            var crypto = new HMACSHA1();
            var key = "{0}&{1}".FormatWith(consumerSecret, tokenSecret);

            crypto.Key = _encoding.GetBytes(key);
            signature = signatureBase.HashWith(crypto);

            break;
        }
        case OAuthSignatureMethod.PlainText:
        {
            signature = "{0}&{1}".FormatWith(consumerSecret, tokenSecret);

            break;
        }
        default:
            throw new NotImplementedException("Only HMAC-SHA1 is currently supported.");
        }

        var result = signatureTreatment == OAuthSignatureTreatment.Escaped
            ? UrlEncodeRelaxed(signature)
            : signature;

        return result;
    }

언급URL : https://stackoverflow.com/questions/13972898/unable-to-use-plaintext-signature-with-a-dotnetopenauth-serviceprovider

반응형