diff --git a/SampleApplications/Samples/GDS/App.config b/SampleApplications/Samples/GDS/App.config
index 1b397f1b74..4fbd7a2c74 100644
--- a/SampleApplications/Samples/GDS/App.config
+++ b/SampleApplications/Samples/GDS/App.config
@@ -3,8 +3,8 @@
-
-
+
+
diff --git a/SampleApplications/Samples/GDS/AuthorizationService.cs b/SampleApplications/Samples/GDS/AuthorizationService.cs
deleted file mode 100644
index 138c3e9601..0000000000
--- a/SampleApplications/Samples/GDS/AuthorizationService.cs
+++ /dev/null
@@ -1,449 +0,0 @@
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Owin.Hosting;
-using Owin;
-using IdentityServer3.Core.Configuration;
-using IdentityServer3.Core.Models;
-using IdentityServer3.Core.Services;
-using IdentityServer3.Core.Validation;
-using IdentityServer3.Core.Services.Default;
-using System.Security.Cryptography.X509Certificates;
-using Opc.Ua.Configuration;
-using Serilog;
-using System.Security.Claims;
-using Microsoft.Owin;
-using System.IO;
-using IdentityServer3.Core.Services.InMemory;
-using System.IdentityModel.Tokens.Jwt;
-
-namespace Opc.Ua.AuthorizationService
-{
- public class AuthorizationService
- {
- private IDisposable m_host;
- private ApplicationInstance m_application;
-
- public async void Start(ApplicationInstance application)
- {
- Startup.ServiceCertificate = await application.ApplicationConfiguration.SecurityConfiguration.ApplicationCertificate.Find();
-
- string hostname = System.Net.Dns.GetHostName();
-
- foreach (var baseAddress in application.ApplicationConfiguration.ServerConfiguration.BaseAddresses)
- {
- Uri url = new Uri(baseAddress);
-
- if (url.Scheme == "https" && url.DnsSafeHost != "localhost")
- {
- hostname = url.DnsSafeHost;
- break;
- }
- }
-
- Log.Logger = new LoggerConfiguration()
- .MinimumLevel.Debug()
- .WriteTo.LiterateConsole()
- .CreateLogger();
-
- m_host = WebApp.Start(String.Format("https://{0}:54333", hostname));
- m_application = application;
- }
- }
-
- public class Startup
- {
- public static X509Certificate2 ServiceCertificate;
-
- public void Configuration(IAppBuilder app)
- {
- var factory = new IdentityServerServiceFactory().UseInMemoryScopes(Scopes.Get()).UseInMemoryUsers(Users.Get());
-
- factory.TokenService = new Registration(typeof(CustomTokenService));
- factory.CorsPolicyService = new Registration(new DefaultCorsPolicyService { AllowAll = true });
- factory.SecretParsers = new Registration[] { new Registration(new ApplicationCertificateSecretParser()) };
- factory.SecretValidators = new Registration[] { new Registration(new ApplicationCertificateSecretValidator()) };
- factory.ClientStore = new Registration(new ApplicationClientStore());
- factory.CustomGrantValidators.Add(new Registration(typeof(CustomGrantValidator)));
-
- var options = new IdentityServerOptions
- {
- SiteName = "GDS AuthorizationService",
-
- SigningCertificate = LoadCertificate(),
- Factory = factory,
- InputLengthRestrictions = new InputLengthRestrictions() { Password = 2048 },
-
- EventsOptions = new EventsOptions
- {
- RaiseSuccessEvents = true,
- RaiseErrorEvents = true,
- RaiseFailureEvents = true,
- RaiseInformationEvents = true
- },
- };
-
- app.UseIdentityServer(options);
- }
-
- X509Certificate2 LoadCertificate()
- {
- return Startup.ServiceCertificate;
- }
- }
-
- static class Users
- {
- public static List Get()
- {
- return new List();
- }
- }
-
- static class Scopes
- {
- public static List Get()
- {
- return new List
- {
- new Scope { Name = "gdsadmin" },
- new Scope { Name = "appadmin" },
- new Scope { Name = "pubsub" },
- new Scope { Name = "pubsub:secret" },
- new Scope { Name = "observer" }
- };
- }
- }
-
- public class ApplicationClientStore : IClientStore
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The inner .
- /// The cache.
- ///
- /// inner
- /// or
- /// cache
- ///
- public ApplicationClientStore()
- {
- }
-
- ///
- /// Finds a client by id
- ///
- /// The client id
- ///
- /// The client
- ///
- public Task FindClientByIdAsync(string clientId)
- {
- if (clientId == "urn:localhost:OAuth2TestClient")
- {
- return Task.FromResult(new IdentityServer3.Core.Models.Client
- {
- ClientName = "OAuth2TestClient",
- ClientId = clientId,
- Enabled = true,
- AccessTokenType = AccessTokenType.Jwt,
- Flow = Flows.ClientCredentials,
- ClientSecrets = new List { new Secret("secret".Sha256()) },
- AllowClientCredentialsOnly = true,
- AllowAccessToAllScopes = true
- });
- }
-
- // TBD - look up ApplicationUri in DB.
-
- return Task.FromResult(new IdentityServer3.Core.Models.Client
- {
- ClientName = "Global Discovery Client",
- ClientId = clientId,
- Enabled = true,
- AccessTokenType = AccessTokenType.Jwt,
- Flow = Flows.Custom,
- ClientSecrets = new List(),
- AllowAccessToAllCustomGrantTypes = true,
- AllowedCustomGrantTypes = new List { "urn:opcfoundation.org:oauth2:site_token" },
- AllowAccessToAllScopes = true
- });
- }
- }
-
- ///
- /// Parses the environment for an X509 client certificate
- ///
- public class ApplicationCertificateSecretParser : ISecretParser
- {
- ///
- /// Tries to find a secret on the environment that can be used for authentication
- ///
- /// The environment.
- ///
- /// A parsed secret
- ///
- public async Task ParseAsync(IDictionary environment)
- {
- var context = new OwinContext(environment);
-
- if (!context.Request.Body.CanSeek)
- {
- var copy = new MemoryStream();
- await context.Request.Body.CopyToAsync(copy);
- copy.Seek(0L, SeekOrigin.Begin);
- context.Request.Body = copy;
- }
-
- context.Request.Body.Seek(0L, SeekOrigin.Begin);
- var body = await context.Request.ReadFormAsync();
- context.Request.Body.Seek(0L, SeekOrigin.Begin);
-
- var grantType = body.Get("grant_type");
-
- if (String.IsNullOrEmpty(grantType))
- {
- return null;
- }
-
- var clientId = body.Get("client_id");
-
- if (String.IsNullOrEmpty(clientId))
- {
- return null;
- }
-
- var clientSecret = body.Get("client_secret");
-
- if (String.IsNullOrEmpty(clientSecret))
- {
- return null;
- }
-
- if (grantType == "client_credentials")
- {
- return new ParsedSecret
- {
- Id = clientId,
- Credential = clientSecret.Sha256(),
- Type = "SharedSecret"
- };
- }
-
- var certificate = Convert.FromBase64String(clientId);
-
- var signature = Convert.FromBase64String(clientSecret);
-
- var data = body.Get("access_token");
-
- if (String.IsNullOrEmpty(data))
- {
- return null;
- }
-
- var accessToken = data;
-
- data = body.Get("nonce");
-
- if (String.IsNullOrEmpty(data))
- {
- return null;
- }
-
- var nonce = Convert.FromBase64String(data);
-
- try
- {
- X509Certificate2 x509 = new X509Certificate2(certificate);
- // TBD - use a CertificateValidator to verify certificate.
-
- // check that the id matches the certificate.
- var applicationUri = Utils.GetApplicationUriFromCertificate(x509);
-
- // verify signature.
- var dataToVerify = Utils.Append(new UTF8Encoding(false).GetBytes(accessToken), nonce);
-
- if (!RsaUtils.RsaPkcs15Sha1_Verify(new ArraySegment(dataToVerify), signature, x509))
- {
- return null;
- }
-
- return new ParsedSecret
- {
- Id = applicationUri,
- Credential = x509,
- Type = "ApplicationSignature"
- };
- }
- catch (Exception)
- {
- return null;
- }
- }
- }
-
- ///
- /// Validates a secret based on the thumbprint of an X509 Certificate
- ///
- public class ApplicationCertificateSecretValidator : ISecretValidator
- {
- ///
- /// Validates a secret
- ///
- /// The stored secrets.
- /// The received secret.
- ///
- /// A validation result
- ///
- /// ParsedSecret.Credential is not an X509 Certificate
- public Task ValidateAsync(IEnumerable secrets, ParsedSecret parsedSecret)
- {
- var fail = Task.FromResult(new SecretValidationResult { Success = false });
- var success = Task.FromResult(new SecretValidationResult { Success = true });
-
- if (parsedSecret.Type == "SharedSecret")
- {
- foreach (var secret in secrets)
- {
- if (secret.Value.Equals(parsedSecret.Credential))
- {
- return success;
- }
- }
-
- return fail;
- }
-
- if (parsedSecret.Type != "ApplicationSignature")
- {
- return fail;
- }
-
- var certificate = parsedSecret.Credential as X509Certificate2;
-
- if (certificate == null)
- {
- throw new ArgumentException("ParsedSecret.Credential is not an X509 Certificate");
- }
-
- return success;
- }
- }
-
- class CustomGrantValidator : ICustomGrantValidator
- {
- public Task ValidateAsync(ValidatedTokenRequest request)
- {
- var accessToken = request.Raw.Get("access_token");
- var identity = JwtUtils.ValidateToken(new Uri("https://login.microsoftonline.com/opcfoundationprototyping.onmicrosoft.com"), "https://localhost:62540/prototypeserver", accessToken);
- IssuedIdentityToken token = identity.GetIdentityToken() as IssuedIdentityToken;
- JwtSecurityToken azureToken = new JwtSecurityToken(new UTF8Encoding(false).GetChars(token.DecryptedTokenData).ToString());
-
- var scope = request.Raw.Get("scope");
- var nonce = request.Raw.Get("nonce");
-
- DateTime now = DateTime.UtcNow;
- double maxClockSkewInMinutes = 10;
-
- if (azureToken.ValidFrom.AddMinutes(-maxClockSkewInMinutes) > now || azureToken.ValidTo.AddMinutes(maxClockSkewInMinutes) < now)
- {
- return Task.FromResult(new CustomGrantValidationResult(
- "Access token provided with the request has expired (" +
- azureToken.ValidTo.ToLocalTime().ToString("yyy-MM-dd HH:mm:ss") +
- ") or is not yet valid (" +
- azureToken.ValidFrom.ToLocalTime().ToString("yyy-MM-dd HH:mm:ss") + ")."));
- }
-
- List claims = new List();
- string subject = request.Client.ClientId;
-
- foreach (var claim in azureToken.Claims)
- {
- switch (claim.Type)
- {
- case "unique_name": { subject = claim.Value; claims.Add(claim); break; }
- case "name": { claims.Add(claim); break; }
- }
- }
-
- claims.Add(new Claim("nonce", nonce));
-
- request.Client.AccessTokenLifetime = (int)(azureToken.ValidTo - now).TotalSeconds;
-
- var result = new CustomGrantValidationResult(
- subject,
- "site_token",
- claims,
- "gds");
-
- return Task.FromResult(result);
- }
-
- public string GrantType
- {
- get { return "urn:opcfoundation.org:oauth2:site_token"; }
- }
- }
-
- class CustomTokenService : DefaultTokenService
- {
- public CustomTokenService(IdentityServerOptions options, IClaimsProvider claimsProvider, ITokenHandleStore tokenHandles, ITokenSigningService signingService, IEventService events)
- : base(options, claimsProvider, tokenHandles, signingService, events)
- {
- }
-
- public async override Task CreateAccessTokenAsync(TokenCreationRequest request)
- {
- var token = await base.CreateAccessTokenAsync(request);
-
- token.Lifetime = token.Client.AccessTokenLifetime;
-
- /*
- var claims = new List();
- claims.AddRange(await _claimsProvider.GetAccessTokenClaimsAsync(
- request.Subject,
- request.Client,
- request.Scopes,
- request.ValidatedRequest));
-
- if (request.Client.IncludeJwtId)
- {
- claims.Add(new Claim(Constants.ClaimTypes.JwtId, CryptoRandom.CreateUniqueId()));
- }
-
- if (request.ProofKey.IsPresent())
- {
- claims.Add(new Claim(Constants.ClaimTypes.Confirmation, request.ProofKey, Constants.ClaimValueTypes.Json));
- }
-
- var token = new Token(Constants.TokenTypes.AccessToken)
- {
- Audience = string.Format(Constants.AccessTokenAudience, IssuerUri.EnsureTrailingSlash()),
- Issuer = IssuerUri,
- Lifetime = request.Client.AccessTokenLifetime,
- Claims = claims.Distinct(new ClaimComparer()).ToList(),
- Client = request.Client
- };
- */
-
- var resource = request.ValidatedRequest.Raw["resource"];
-
- if (String.IsNullOrEmpty(resource))
- {
- token.Audience = Namespaces.OAuth2SiteResourceUri;
- }
- else
- {
- token.Audience = resource;
- }
-
- UriBuilder uri = new UriBuilder(token.Issuer);
- uri.Host = uri.Host.ToLowerInvariant();
- token.Issuer = uri.ToString();
-
- return token;
- }
- }
-}
diff --git a/SampleApplications/Samples/GDS/GlobalDiscoveryServer.csproj b/SampleApplications/Samples/GDS/GlobalDiscoveryServer.csproj
index 01ebb4f41a..5c46175126 100644
--- a/SampleApplications/Samples/GDS/GlobalDiscoveryServer.csproj
+++ b/SampleApplications/Samples/GDS/GlobalDiscoveryServer.csproj
@@ -68,34 +68,6 @@
..\..\..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll
True
-
- ..\..\..\packages\IdentityServer3.2.5.1\lib\net45\IdentityServer3.dll
- True
-
-
- ..\..\..\packages\Microsoft.IdentityModel.Logging.1.0.0\lib\net451\Microsoft.IdentityModel.Logging.dll
- True
-
-
- ..\..\..\packages\Microsoft.IdentityModel.Tokens.5.0.0\lib\net451\Microsoft.IdentityModel.Tokens.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll
- True
-
-
- ..\..\..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll
- True
-
-
- ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
- True
-
False
..\..\SDK\Opc.Ua.Configuration\bin\Debug\net46\Opc.Ua.Configuration.dll
@@ -108,18 +80,6 @@
False
..\..\SDK\Opc.Ua.Server\bin\Debug\net46\Opc.Ua.Server.dll
-
- ..\..\..\packages\Owin.1.0\lib\net40\Owin.dll
- True
-
-
- ..\..\..\packages\Serilog.2.1.0\lib\net45\Serilog.dll
- True
-
-
- ..\..\..\packages\Serilog.Sinks.Literate.2.0.0\lib\net45\Serilog.Sinks.Literate.dll
- True
-
@@ -133,38 +93,24 @@
3.0
-
- ..\..\..\packages\System.IdentityModel.Tokens.Jwt.5.0.0\lib\net451\System.IdentityModel.Tokens.Jwt.dll
- True
-
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
- True
-
3.0
3.0
-
- ..\..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
- True
-
-
-
ResXFileCodeGenerator
Resources.Designer.cs
diff --git a/SampleApplications/Samples/GDS/GlobalDiscoveryServerServer.cs b/SampleApplications/Samples/GDS/GlobalDiscoveryServerServer.cs
index 00c01ab8a0..c1328dd017 100644
Binary files a/SampleApplications/Samples/GDS/GlobalDiscoveryServerServer.cs and b/SampleApplications/Samples/GDS/GlobalDiscoveryServerServer.cs differ
diff --git a/SampleApplications/Samples/GDS/Program.cs b/SampleApplications/Samples/GDS/Program.cs
index 877fcaee0b..4d60479e0d 100644
--- a/SampleApplications/Samples/GDS/Program.cs
+++ b/SampleApplications/Samples/GDS/Program.cs
@@ -62,13 +62,6 @@ namespace Opc.Ua.GdsServer
Task task2 = application.CheckApplicationInstanceCertificate(false, 0);
task2.Wait();
- // add handler.
- application.ApplicationConfiguration.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation;
-
- // start authorization service.
- var aus = new Opc.Ua.AuthorizationService.AuthorizationService();
- aus.Start(application);
-
// start the server.
var server = new GlobalDiscoveryServerServer();
Task task3 = application.Start(server);
@@ -83,14 +76,5 @@ namespace Opc.Ua.GdsServer
return;
}
}
-
- static void CertificateValidator_CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
- {
- // automatically accept all untrusted certficates.
- if (e.Error.Code == StatusCodes.BadCertificateUntrusted)
- {
- e.Accept = true;
- }
- }
}
}
diff --git a/SampleApplications/Samples/GDS/SelfHost.cs b/SampleApplications/Samples/GDS/SelfHost.cs
deleted file mode 100644
index 092142fa36..0000000000
--- a/SampleApplications/Samples/GDS/SelfHost.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Web.Http;
-
-namespace Opc.Ua.GdsServer
-{
- public class ProductsController : ApiController
- {
- Product[] products = new Product[]
- {
- new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
- new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
- new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
- };
-
- public IEnumerable GetAllProducts()
- {
- return products;
- }
-
- public Product GetProductById(int id)
- {
- var product = products.FirstOrDefault((p) => p.Id == id);
- if (product == null)
- {
- throw new HttpResponseException(HttpStatusCode.NotFound);
- }
- return product;
- }
-
- public IEnumerable GetProductsByCategory(string category)
- {
- return products.Where(p => string.Equals(p.Category, category,
- StringComparison.OrdinalIgnoreCase));
- }
- }
-
- public class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Category { get; set; }
- public decimal Price { get; set; }
- }
-}
diff --git a/SampleApplications/Samples/GDS/packages.config b/SampleApplications/Samples/GDS/packages.config
index 049bfbdf44..c089e85e2e 100644
--- a/SampleApplications/Samples/GDS/packages.config
+++ b/SampleApplications/Samples/GDS/packages.config
@@ -1,17 +1,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file