test/SampleService/App_Code/Entities.cs in ruby_odata-0.0.7 vs test/SampleService/App_Code/Entities.cs in ruby_odata-0.0.8
- old
+ new
@@ -1,10 +1,14 @@
using System.Data.Services;
using System.Data.Services.Common;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Web;
+using System;
+using System.Linq;
+using System.Security.Principal;
+using System.Text;
using Model;
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Entities : DataService< ModelContainer >
{
@@ -27,16 +31,115 @@
context.ExecuteStoreCommand("ALTER TABLE [dbo].[Products] DROP CONSTRAINT [FK_CategoryProduct]");
context.ExecuteStoreCommand("TRUNCATE TABLE [dbo].[Categories]; TRUNCATE TABLE [dbo].[Products]");
context.ExecuteStoreCommand("ALTER TABLE [dbo].[Products] ADD CONSTRAINT [FK_CategoryProduct] FOREIGN KEY ([Category_Id]) REFERENCES [dbo].[Categories]([Id])");
}
-
+
protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
base.OnStartProcessingRequest(args);
if (args.RequestUri.AbsoluteUri.ToLower().EndsWith("cleandatabasefortesting"))
{
- if (HttpContext.Current.Request.UserHostAddress != "127.0.0.1")
+ var hostAddress = HttpContext.Current.Request.UserHostAddress;
+ if (hostAddress != "127.0.0.1" && hostAddress != "::1")
throw new DataServiceException(401, "Access Denied");
}
}
}
+
+public class OurBasicAuthenticationModule: IHttpModule
+{
+ public void Init(HttpApplication context)
+ {
+ context.AuthenticateRequest
+ += new EventHandler(context_AuthenticateRequest);
+ }
+
+ void context_AuthenticateRequest(object sender, EventArgs e)
+ {
+ HttpApplication application = (HttpApplication)sender;
+
+ // Only require authentication if BasicAuth is in the URI path
+ if (( application.Context.Request.Url.AbsoluteUri.Contains("BasicAuth")) &&
+ (!CustomBasicAuthenticationProvider.Authenticate(application.Context)))
+ {
+ application.Context.Response.Status = "401 Unauthorized";
+ application.Context.Response.StatusCode = 401;
+ application.Context.Response.AddHeader("WWW-Authenticate", "Basic");
+ application.CompleteRequest();
+ }
+ }
+
+ public void Dispose() { }
+
+} // class OurBasicAuthenticationModule: IHttpModule
+
+public class CustomBasicAuthenticationProvider
+{
+ public static bool Authenticate(HttpContext context)
+ {
+ if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization"))
+ return false;
+
+ string authHeader = HttpContext.Current.Request.Headers["Authorization"];
+
+ IPrincipal principal;
+ if (TryGetPrincipal(authHeader, out principal))
+ {
+ HttpContext.Current.User = principal;
+ return true;
+ }
+ return false;
+ }
+
+ private static bool TryGetPrincipal(string authHeader, out IPrincipal principal)
+ {
+ var creds = ParseAuthHeader(authHeader);
+ if (creds != null && TryGetPrincipal(creds, out principal))
+ return true;
+
+ principal = null;
+ return false;
+ }
+
+ private static bool TryGetPrincipal(string[] creds,out IPrincipal principal)
+ {
+ if (creds[0] == "admin" && creds[1] == "passwd")
+ {
+ principal = new GenericPrincipal(
+ new GenericIdentity("Administrator"),
+ new string[] {"Administrator", "User"}
+ );
+ return true;
+ }
+ else
+ {
+ principal = null;
+ return false;
+ }
+ }
+
+ private static string[] ParseAuthHeader(string authHeader)
+ {
+ // Check this is a Basic Auth header
+ if (
+ authHeader == null ||
+ authHeader.Length == 0 ||
+ !authHeader.StartsWith("Basic")
+ ) return null;
+
+ // Pull out the Credentials with are seperated by ':' and Base64 encoded
+ // Won't handle password with : in it, but that's OK for these tests
+ string base64Credentials = authHeader.Substring(6);
+ string[] credentials = Encoding.ASCII.GetString(
+ Convert.FromBase64String(base64Credentials)
+ ).Split(new char[] { ':' });
+
+ if (credentials.Length != 2 ||
+ string.IsNullOrEmpty(credentials[0]) ||
+ string.IsNullOrEmpty(credentials[0])
+ ) return null;
+
+ return credentials;
+ }
+
+} // class CustomBasicAuthenticationProvider