Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Make HttpRavenRequestFactory support BasicAuthenticator also

  • Loading branch information...
commit aefc21273ba8f14eefc53ba8ea3b3fe2e1a654b4 1 parent a235137
@emertechie emertechie authored
View
47 Raven.Abstractions/Connection/HttpRavenRequestFactory.cs
@@ -11,26 +11,36 @@ public class HttpRavenRequestFactory
{
public int? RequestTimeoutInMs { get; set; }
- readonly ConcurrentDictionary<string, SecuredAuthenticator> authenticators = new ConcurrentDictionary<string, SecuredAuthenticator>();
+ readonly ConcurrentDictionary<string, AbstractAuthenticator> authenticators = new ConcurrentDictionary<string, AbstractAuthenticator>();
public void ConfigureRequest(RavenConnectionStringOptions options, WebRequest request)
{
if (RequestTimeoutInMs.HasValue)
request.Timeout = RequestTimeoutInMs.Value;
-
if (options.ApiKey == null)
{
request.Credentials = options.Credentials ?? CredentialCache.DefaultNetworkCredentials;
return;
}
- var value = authenticators.GetOrAdd(options.ApiKey, s => new SecuredAuthenticator(s));
+ var webRequestEventArgs = new WebRequestEventArgs { Request = request };
- value.ConfigureRequest(this, new WebRequestEventArgs
+ AbstractAuthenticator existingAuthenticator;
+ if (authenticators.TryGetValue(options.ApiKey, out existingAuthenticator))
+ {
+ existingAuthenticator.ConfigureRequest(this, webRequestEventArgs);
+ }
+ else
{
- Request = request
- });
+ // TODO: Not sure where to get this or if it's needed
+ bool enableBasicAuthenticationOverUnsecuredHttp = false;
+ var basicAuthenticator = new BasicAuthenticator(options.ApiKey, enableBasicAuthenticationOverUnsecuredHttp);
+ var securedAuthenticator = new SecuredAuthenticator(options.ApiKey);
+
+ basicAuthenticator.ConfigureRequest(this, webRequestEventArgs);
+ securedAuthenticator.ConfigureRequest(this, webRequestEventArgs);
+ }
}
public HttpRavenRequest Create(string url, string method, RavenConnectionStringOptions connectionStringOptions)
@@ -43,11 +53,30 @@ private bool HandleUnauthorizedResponse(RavenConnectionStringOptions options, We
if (options.ApiKey == null)
return false;
- var value = authenticators.GetOrAdd(options.ApiKey, s => new SecuredAuthenticator(s));
+ var oauthSource = webResponse.Headers["OAuth-Source"];
+
+ var useBasicAuthenticator =
+ string.IsNullOrEmpty(oauthSource) == false &&
+ oauthSource.EndsWith("/OAuth/API-Key", StringComparison.CurrentCultureIgnoreCase) == false;
+
+ var authenticator = authenticators.GetOrAdd(
+ options.ApiKey,
+ apiKey =>
+ {
+ if (useBasicAuthenticator)
+ {
+ // TODO: Not sure where to get this or if it's needed
+ bool enableBasicAuthenticationOverUnsecuredHttp = false;
+ return new BasicAuthenticator(apiKey, enableBasicAuthenticationOverUnsecuredHttp);
+ }
+
+ return new SecuredAuthenticator(apiKey);
+ });
- var oauthSource = options.Url + "/OAuth/API-Key";
+ if (useBasicAuthenticator == false)
+ oauthSource = options.Url + "/OAuth/API-Key";
- var result = value.DoOAuthRequest(oauthSource);
+ var result = authenticator.DoOAuthRequest(oauthSource);
return result != null;
}
}
View
4 Raven.Abstractions/OAuth/AbstractAuthenticator.cs
@@ -27,5 +27,9 @@ protected static void SetHeader(WebHeaderCollection headers, string key, string
throw new InvalidOperationException("Could not set '" + key + "' = '" + value + "'", e);
}
}
+
+ #if !SILVERLIGHT
+ public abstract Action<HttpWebRequest> DoOAuthRequest(string oauthSource);
+ #endif
}
}
View
22 ...ight/Document/OAuth/BasicAuthenticator.cs → ....Abstractions/OAuth/BasicAuthenticator.cs
@@ -4,25 +4,24 @@
using System.Threading.Tasks;
using Raven.Abstractions.Connection;
using Raven.Abstractions.Extensions;
-using Raven.Abstractions.OAuth;
-using Raven.Client.Connection;
-using Raven.Client.Extensions;
+
#if SILVERLIGHT
+using Raven.Client.Connection;
using Raven.Client.Silverlight.Connection;
using System.Net.Browser;
#endif
-namespace Raven.Client.Document.OAuth
+namespace Raven.Abstractions.OAuth
{
public class BasicAuthenticator : AbstractAuthenticator
{
private readonly string apiKey;
- private readonly HttpJsonRequestFactory jsonRequestFactory;
-
- public BasicAuthenticator(string apiKey, HttpJsonRequestFactory jsonRequestFactory)
+ private readonly bool enableBasicAuthenticationOverUnsecuredHttp;
+
+ public BasicAuthenticator(string apiKey, bool enableBasicAuthenticationOverUnsecuredHttp)
{
this.apiKey = apiKey;
- this.jsonRequestFactory = jsonRequestFactory;
+ this.enableBasicAuthenticationOverUnsecuredHttp = enableBasicAuthenticationOverUnsecuredHttp;
}
@@ -48,7 +47,7 @@ public Task<Action<HttpWebRequest>> HandleOAuthResponseAsync(string oauthSource)
}
#if !SILVERLIGHT
- public Action<HttpWebRequest> HandleOAuthResponse(string oauthSource)
+ public override Action<HttpWebRequest> DoOAuthRequest(string oauthSource)
{
var authRequest = PrepareOAuthRequest(oauthSource);
using (var response = authRequest.GetResponse())
@@ -71,15 +70,16 @@ private HttpWebRequest PrepareOAuthRequest(string oauthSource)
#else
var authRequest = (HttpWebRequest) WebRequestCreator.ClientHttp.Create(new Uri(oauthSource.NoCache()));
#endif
+
authRequest.Headers["grant_type"] = "client_credentials";
authRequest.Accept = "application/json;charset=UTF-8";
if (String.IsNullOrEmpty(apiKey) == false)
SetHeader(authRequest.Headers, "Api-Key", apiKey);
- if (oauthSource.StartsWith("https", StringComparison.InvariantCultureIgnoreCase) == false &&
- jsonRequestFactory.EnableBasicAuthenticationOverUnsecuredHttpEvenThoughPasswordsWouldBeSentOverTheWireInClearTextToBeStolenByHackers == false)
+ if (oauthSource.StartsWith("https", StringComparison.InvariantCultureIgnoreCase) == false && enableBasicAuthenticationOverUnsecuredHttp == false)
throw new InvalidOperationException(BasicOAuthOverHttpError);
+
return authRequest;
}
View
2  Raven.Abstractions/OAuth/SecuredAuthenticator.cs
@@ -94,7 +94,7 @@ public override void ConfigureRequest(object sender, WebRequestEventArgs e)
#if !SILVERLIGHT
- public Action<HttpWebRequest> DoOAuthRequest(string oauthSource)
+ public override Action<HttpWebRequest> DoOAuthRequest(string oauthSource)
{
string serverRSAExponent = null;
string serverRSAModulus = null;
View
1  Raven.Abstractions/Raven.Abstractions.csproj
@@ -685,6 +685,7 @@
<Compile Include="Data\QueryResult.cs" />
<Compile Include="Indexing\SortOptions.cs" />
<Compile Include="OAuth\AbstractAuthenticator.cs" />
+ <Compile Include="OAuth\BasicAuthenticator.cs" />
<Compile Include="OAuth\SecuredAuthenticator.cs" />
<Compile Include="Replication\ReplicationDestination.cs" />
<Compile Include="Replication\ReplicationDocument.cs" />
View
5 Raven.Client.Lightweight/Document/DocumentStore.cs
@@ -17,7 +17,6 @@
using Raven.Client.Changes;
using Raven.Client.Connection;
using Raven.Client.Connection.Profiling;
-using Raven.Client.Document.OAuth;
using Raven.Client.Extensions;
using Raven.Client.Connection.Async;
using System.Threading.Tasks;
@@ -471,7 +470,7 @@ private void InitializeSecurity()
Credentials = null;
}
- var basicAuthenticator = new BasicAuthenticator(ApiKey, jsonRequestFactory);
+ var basicAuthenticator = new BasicAuthenticator(ApiKey, jsonRequestFactory.EnableBasicAuthenticationOverUnsecuredHttpEvenThoughPasswordsWouldBeSentOverTheWireInClearTextToBeStolenByHackers);
var securedAuthenticator = new SecuredAuthenticator(ApiKey);
jsonRequestFactory.ConfigureRequest += basicAuthenticator.ConfigureRequest;
@@ -486,7 +485,7 @@ private void InitializeSecurity()
if (string.IsNullOrEmpty(oauthSource) == false &&
oauthSource.EndsWith("/OAuth/API-Key", StringComparison.CurrentCultureIgnoreCase) == false)
{
- return basicAuthenticator.HandleOAuthResponse(oauthSource);
+ return basicAuthenticator.DoOAuthRequest(oauthSource);
}
if (ApiKey == null)
View
1  Raven.Client.Lightweight/Raven.Client.Lightweight.csproj
@@ -102,7 +102,6 @@
<Compile Include="Document\GenerateEntityIdOnTheClient.cs" />
<Compile Include="Document\EntityToJson.cs" />
<Compile Include="Document\MultiDatabaseHiLoGenerator.cs" />
- <Compile Include="Document\OAuth\BasicAuthenticator.cs" />
<Compile Include="Document\RemoteBulkInsertOperation.cs" />
<Compile Include="Document\BulkInsertOperation.cs" />
<Compile Include="Exceptions\ServerRequestError.cs" />
View
94 Raven.Client.Silverlight/Imports/Document/OAuth/BasicAuthenticator.cs
@@ -1,94 +0,0 @@
-using System;
-using System.IO;
-using System.Net;
-using System.Threading.Tasks;
-using Raven.Abstractions.Connection;
-using Raven.Abstractions.Extensions;
-using Raven.Abstractions.OAuth;
-using Raven.Client.Connection;
-using Raven.Client.Extensions;
-#if SILVERLIGHT
-using Raven.Client.Silverlight.Connection;
-using System.Net.Browser;
-#endif
-
-namespace Raven.Client.Document.OAuth
-{
- public class BasicAuthenticator : AbstractAuthenticator
- {
- private readonly string apiKey;
- private readonly HttpJsonRequestFactory jsonRequestFactory;
-
- public BasicAuthenticator(string apiKey, HttpJsonRequestFactory jsonRequestFactory)
- {
- this.apiKey = apiKey;
- this.jsonRequestFactory = jsonRequestFactory;
- }
-
-
- public Task<Action<HttpWebRequest>> HandleOAuthResponseAsync(string oauthSource)
- {
- var authRequest = PrepareOAuthRequest(oauthSource);
- return Task<WebResponse>.Factory.FromAsync(authRequest.BeginGetResponse, authRequest.EndGetResponse, null)
- .AddUrlIfFaulting(authRequest.RequestUri)
- .ConvertSecurityExceptionToServerNotFound()
- .ContinueWith(task =>
- {
-#if !SILVERLIGHT
- using (var stream = task.Result.GetResponseStreamWithHttpDecompression())
-#else
- using(var stream = task.Result.GetResponseStream())
-#endif
- using (var reader = new StreamReader(stream))
- {
- CurrentOauthToken = "Bearer " + reader.ReadToEnd();
- return (Action<HttpWebRequest>) (request => SetHeader(request.Headers, "Authorization", CurrentOauthToken));
- }
- });
- }
-
-#if !SILVERLIGHT
- public Action<HttpWebRequest> HandleOAuthResponse(string oauthSource)
- {
- var authRequest = PrepareOAuthRequest(oauthSource);
- using (var response = authRequest.GetResponse())
- {
- using (var stream = response.GetResponseStreamWithHttpDecompression())
- using (var reader = new StreamReader(stream))
- {
- CurrentOauthToken = "Bearer " + reader.ReadToEnd();
- return request => SetHeader(request.Headers, "Authorization", CurrentOauthToken);
- }
- }
- }
-#endif
-
- private HttpWebRequest PrepareOAuthRequest(string oauthSource)
- {
-#if !SILVERLIGHT
- var authRequest = (HttpWebRequest)WebRequest.Create(oauthSource);
- authRequest.Headers["Accept-Encoding"] = "deflate,gzip";
-#else
- var authRequest = (HttpWebRequest) WebRequestCreator.ClientHttp.Create(new Uri(oauthSource.NoCache()));
-#endif
- authRequest.Headers["grant_type"] = "client_credentials";
- authRequest.Accept = "application/json;charset=UTF-8";
-
- if (String.IsNullOrEmpty(apiKey) == false)
- SetHeader(authRequest.Headers, "Api-Key", apiKey);
-
- if (oauthSource.StartsWith("https", StringComparison.InvariantCultureIgnoreCase) == false &&
- jsonRequestFactory.EnableBasicAuthenticationOverUnsecuredHttpEvenThoughPasswordsWouldBeSentOverTheWireInClearTextToBeStolenByHackers == false)
- throw new InvalidOperationException(BasicOAuthOverHttpError);
- return authRequest;
- }
-
- private const string BasicOAuthOverHttpError = @"Attempting to authenticate using basic security over HTTP would expose user credentials (including the password) in clear text to anyone sniffing the network.
-Your OAuth endpoint should be using HTTPS, not HTTP, as the transport mechanism.
-You can setup the OAuth endpoint in the RavenDB server settings ('Raven/OAuthTokenServer' configuration value), or setup your own behavior by providing a value for:
- documentStore.Conventions.HandleUnauthorizedResponse
-If you are on an internal network or requires this for testing, you can disable this warning by calling:
- documentStore.JsonRequestFactory.EnableBasicAuthenticationOverUnsecuredHttpEvenThoughPasswordsWouldBeSentOverTheWireInClearTextToBeStolenByHackers = true;
-";
- }
-}
View
4 Raven.Client.Silverlight/Raven.Client.Silverlight.csproj
@@ -793,6 +793,9 @@
<Compile Include="..\Raven.Abstractions\OAuth\AbstractAuthenticator.cs">
<Link>Imports\Document\OAuth\AbstractAuthenticator.cs</Link>
</Compile>
+ <Compile Include="..\Raven.Abstractions\OAuth\BasicAuthenticator.cs">
+ <Link>Imports\Document\OAuth\BasicAuthenticator.cs</Link>
+ </Compile>
<Compile Include="..\Raven.Abstractions\OAuth\SecuredAuthenticator.cs">
<Link>Imports\Document\OAuth\SecuredAuthenticator.cs</Link>
</Compile>
@@ -1082,7 +1085,6 @@
<Compile Include="Connection\HttpJsonRequestFactory.cs" />
<Compile Include="Connection\HttpJsonRequestHelper.cs" />
<Compile Include="Imports\Connection\WebRequestEventArgs.cs" />
- <Compile Include="Imports\Document\OAuth\BasicAuthenticator.cs" />
<Compile Include="MissingFromSilverlight\CD.cs" />
<Compile Include="MissingFromSilverlight\MD5.cs" />
<Compile Include="DotNetZip\Adler.cs" />
Please sign in to comment.
Something went wrong with that request. Please try again.