diff --git a/OwinWebApiTest/Global.asax b/OwinWebApiTest/Global.asax
deleted file mode 100644
index 3a35a99..0000000
--- a/OwinWebApiTest/Global.asax
+++ /dev/null
@@ -1 +0,0 @@
-<%@ Application Codebehind="Global.asax.cs" Inherits="OwinWebApiTest.WebApiApplication" Language="C#" %>
diff --git a/OwinWebApiTest/Global.asax.cs b/OwinWebApiTest/Global.asax.cs
deleted file mode 100644
index 0f13cfe..0000000
--- a/OwinWebApiTest/Global.asax.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-using System.Web.Http;
-using System.Web.Routing;
-
-namespace OwinWebApiTest
-{
- public class WebApiApplication : System.Web.HttpApplication
- {
- protected void Application_Start()
- {
- //GlobalConfiguration.Configure(WebApiConfig.Register);
- }
- }
-}
diff --git a/OwinWebApiTest/Models/CasServiceValidationResponse.cs b/OwinWebApiTest/Models/CasServiceValidationResponse.cs
new file mode 100644
index 0000000..256cbc8
--- /dev/null
+++ b/OwinWebApiTest/Models/CasServiceValidationResponse.cs
@@ -0,0 +1,20 @@
+namespace OwinWebApiTest.Models
+{
+ public class CasServiceValidationResponse
+ {
+ public CasServiceValidationSuccess success { get; set; }
+ public CasServiceValidationFailure failure { get; set; }
+ }
+
+ public class CasServiceValidationSuccess
+ {
+ public string user { get; set; }
+ public string proxyGrantingTicket { get; set; }
+ }
+
+ public class CasServiceValidationFailure
+ {
+ public string code { get; set; }
+ public string description { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OwinWebApiTest/OwinWebApiTest.csproj b/OwinWebApiTest/OwinWebApiTest.csproj
index b16b24c..a2b6256 100644
--- a/OwinWebApiTest/OwinWebApiTest.csproj
+++ b/OwinWebApiTest/OwinWebApiTest.csproj
@@ -138,22 +138,23 @@
-
-
+
+ Designer
+
-
- Global.asax
-
+
+
+
Web.config
diff --git a/OwinWebApiTest/Properties/PublishProfiles/FileSystem.pubxml b/OwinWebApiTest/Properties/PublishProfiles/FileSystem.pubxml
new file mode 100644
index 0000000..b406743
--- /dev/null
+++ b/OwinWebApiTest/Properties/PublishProfiles/FileSystem.pubxml
@@ -0,0 +1,17 @@
+
+
+
+
+ FileSystem
+ Release
+ Any CPU
+
+ True
+ False
+ D:\devel\aspnet\OwinWebApiTest.deploy
+ True
+
+
\ No newline at end of file
diff --git a/OwinWebApiTest/Providers/CasAuthorizationServerProvider.cs b/OwinWebApiTest/Providers/CasAuthorizationServerProvider.cs
new file mode 100644
index 0000000..962afac
--- /dev/null
+++ b/OwinWebApiTest/Providers/CasAuthorizationServerProvider.cs
@@ -0,0 +1,116 @@
+using Microsoft.Owin.Security.OAuth;
+using Microsoft.Owin.Security;
+using Microsoft.Owin.Infrastructure;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Net.Http;
+using System.Security.Claims;
+using System.Threading.Tasks;
+
+using OwinWebApiTest.Models;
+
+namespace OwinWebApiTest.Providers
+{
+
+ public class CasAuthorizationServerProvider : OAuthAuthorizationServerProvider
+ {
+ private static string casValidationUrl;
+ private static string serviceUser;
+
+ public CasAuthorizationServerProvider()
+ {
+ casValidationUrl = ConfigurationManager.AppSettings["CasHost"]
+ + ConfigurationManager.AppSettings["CasValidationPath"];
+ serviceUser = ConfigurationManager.AppSettings["ServiceUser"];
+ }
+
+ public override async Task ValidateClientAuthentication(
+ OAuthValidateClientAuthenticationContext context)
+ {
+ // required but as we're not using client auth just validate & move on...
+ await Task.FromResult(context.Validated());
+ }
+
+ public override async Task GrantResourceOwnerCredentials(
+ OAuthGrantResourceOwnerCredentialsContext context)
+ {
+ dynamic args = await context.Request.ReadFormAsync();
+
+ if (string.IsNullOrEmpty(args["ticket"]) || string.IsNullOrEmpty(args["service"])) {
+ context.SetError("invalid_grant", "No CAS ticket or service URL sent.");
+ context.Rejected();
+ return;
+ }
+
+ var res = await ValidateCasTicket(args["ticket"], args["service"]);
+
+ if (res.success == null && !string.IsNullOrEmpty(serviceUser)) {
+ res.success = new CasServiceValidationSuccess { user = serviceUser };
+ }
+
+ if (res.success == null) {
+ context.Rejected();
+ context.SetError("invalid_grant", "CAS validation failed: " + (res.failure != null
+ ? res.failure.description : "No response received from the CAS server"));
+ return;
+ }
+
+ //var acda = new AccessControlDA();
+ //var ac = acda.GetAccessControl(res.success.user);
+ var ac = new { userId = args["username"], saveAllowed = true, saveAllUnits = true };
+
+ ClaimsIdentity identity = new ClaimsIdentity(context.Options.AuthenticationType);
+ identity.AddClaim(new Claim(ClaimTypes.Name, res.success.user));
+ identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
+ //identity.AddClaim(new Claim("user_name", context.UserName));
+ //identity.AddClaim(new Claim("sub", context.UserName));
+
+ // Identity info will be encoded into an Access ticket as a result of this call:
+ //context.Validated(identity);
+
+ var props = new AuthenticationProperties(new Dictionary {
+ { "username", res.success.user },
+ { "AccessControl", JsonConvert.SerializeObject(ac) },
+ });
+
+ var ticket = new AuthenticationTicket(identity, props);
+ context.Validated(ticket);
+ }
+
+ private async Task ValidateCasTicket(string ticket, string service)
+ {
+ var requestUri = WebUtilities.AddQueryString(casValidationUrl, new Dictionary() {
+ { "service", service },
+ { "ticket", ticket },
+ { "format", "JSON" },
+ });
+
+ using (HttpClient client = new HttpClient())
+ {
+ return await GetCasServiceValidationAsync(client, requestUri);
+ }
+ }
+
+ public async Task GetCasServiceValidationAsync(
+ HttpClient client, string requestUri)
+ {
+ using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri))
+ {
+ using (HttpResponseMessage response = await client.SendAsync(request))
+ {
+ response.EnsureSuccessStatusCode();
+ dynamic resp = await response.Content.ReadAsAsync();
+ var success = resp.SelectToken("serviceResponse.authenticationSuccess");
+ var failure = resp.SelectToken("serviceResponse.authenticationFailure");
+
+ return new CasServiceValidationResponse() {
+ success = success != null ? success.ToObject() : null,
+ failure = failure != null ? failure.ToObject() : null,
+ };
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OwinWebApiTest/Providers/SimpleAuthorizationServerProvider.cs b/OwinWebApiTest/Providers/SimpleAuthorizationServerProvider.cs
index f1e522b..2d27518 100644
--- a/OwinWebApiTest/Providers/SimpleAuthorizationServerProvider.cs
+++ b/OwinWebApiTest/Providers/SimpleAuthorizationServerProvider.cs
@@ -8,12 +8,12 @@ namespace OwinWebApiTest.Providers
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
- context.Validated();
+ await Task.FromResult(context.Validated());
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
- context.Validated(new ClaimsIdentity(context.Options.AuthenticationType));
+ await Task.FromResult(context.Validated(new ClaimsIdentity(context.Options.AuthenticationType)));
}
}
diff --git a/OwinWebApiTest/Startup.cs b/OwinWebApiTest/Startup.cs
index e1f76f0..c999a2e 100644
--- a/OwinWebApiTest/Startup.cs
+++ b/OwinWebApiTest/Startup.cs
@@ -1,10 +1,12 @@
using System;
+using System.Configuration;
using System.Threading.Tasks;
-using Microsoft.Owin;
using Owin;
-using System.Web.Http;
-using Microsoft.Owin.Security.OAuth;
+using Microsoft.Owin;
using Microsoft.Owin.Cors;
+using Microsoft.Owin.Security.OAuth;
+using System.Web.Http;
+using System.Net;
using OwinWebApiTest.Providers;
@@ -18,13 +20,17 @@ namespace OwinWebApiTest
{
app.UseCors(CorsOptions.AllowAll);
- // token generation
+ double tokenLifetime;
+ double.TryParse(ConfigurationManager.AppSettings["AccessTokenLifetimeHours"], out tokenLifetime);
+
+ // token configuration
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
- TokenEndpointPath = new PathString("/token"),
- AccessTokenExpireTimeSpan = TimeSpan.FromHours(8),
- Provider = new SimpleAuthorizationServerProvider()
+ TokenEndpointPath = new PathString("/api/auth/validate"),
+ AccessTokenExpireTimeSpan = TimeSpan.FromHours(tokenLifetime != 0 ? tokenLifetime : 10),
+ //Provider = new SimpleAuthorizationServerProvider()
+ Provider = new CasAuthorizationServerProvider()
});
// token consumption
@@ -33,6 +39,9 @@ namespace OwinWebApiTest
HttpConfiguration config = new HttpConfiguration();
app.UseWebApi(WebApiConfig.Register(config));
+ // allow self-signed certificates
+ ServicePointManager.ServerCertificateValidationCallback +=
+ (sender, cert, chain, sslPolicyErrors) => true;
}
}
}
diff --git a/OwinWebApiTest/Web.config b/OwinWebApiTest/Web.config
index 67ded2d..d4e2984 100644
--- a/OwinWebApiTest/Web.config
+++ b/OwinWebApiTest/Web.config
@@ -8,7 +8,16 @@
-
+
+
+
+
+
+
+
+