Start of agent bridge code
This commit is contained in:
Родитель
75ad7f6f6c
Коммит
8c2fb2f0aa
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AuthJanitor.AgentBridges
|
||||
{
|
||||
public class AgentActionMessage
|
||||
{
|
||||
public string AgentId { get; set; }
|
||||
public TimeSpan ValidPeriod { get; set; }
|
||||
public IEnumerable<AgentActionMessageProvider> Providers { get; set; } = new AgentActionMessageProvider[0];
|
||||
|
||||
public AgentActionMessage() { }
|
||||
public AgentActionMessage(string agentId, TimeSpan secretValidPeriod, params AgentActionMessageProvider[] providers)
|
||||
{
|
||||
AgentId = agentId;
|
||||
ValidPeriod = secretValidPeriod;
|
||||
Providers = providers;
|
||||
}
|
||||
}
|
||||
public class AgentActionMessageProvider
|
||||
{
|
||||
public string ProviderType { get; set; }
|
||||
public string ProviderConfiguration { get; set; }
|
||||
|
||||
public AgentActionMessageProvider() { }
|
||||
public AgentActionMessageProvider(string providerType, string providerConfiguration)
|
||||
{
|
||||
ProviderType = providerType;
|
||||
ProviderConfiguration = providerConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageEnvelope
|
||||
{
|
||||
public string Signature { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public MessageEnvelope() { }
|
||||
public MessageEnvelope(string signature, string message)
|
||||
{
|
||||
Signature = signature;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
using AuthJanitor.Integrations.CryptographicImplementations;
|
||||
using AuthJanitor.SecureStorage;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AuthJanitor.AgentBridges
|
||||
{
|
||||
public interface IAgentBridge
|
||||
{
|
||||
Task<MessageEnvelope> CreateAgentMessage(string agentId, TimeSpan secretValidPeriod, params AgentActionMessageProvider[] providers);
|
||||
Task<AgentActionMessage> DecryptAgentMessage(MessageEnvelope envelope);
|
||||
}
|
||||
|
||||
public class AzureQueuesAgentBridge : IAgentBridge
|
||||
{
|
||||
private ICryptographicImplementation _cryptographicImplementation;
|
||||
private ISecureStorage _secureStorage;
|
||||
|
||||
public AzureQueuesAgentBridge(
|
||||
ICryptographicImplementation cryptographicImplementation,
|
||||
ISecureStorage secureStorage)
|
||||
{
|
||||
_cryptographicImplementation = cryptographicImplementation;
|
||||
_secureStorage = secureStorage;
|
||||
}
|
||||
|
||||
public async Task<AgentActionMessage> DecryptAgentMessage(MessageEnvelope envelope)
|
||||
{
|
||||
var serverPublicKey = new byte[0];
|
||||
var agentPrivateKey = new byte[0];
|
||||
if (!await _cryptographicImplementation.Verify(serverPublicKey, envelope.Message, envelope.Signature))
|
||||
{
|
||||
throw new Exception("Signature invalid!");
|
||||
}
|
||||
var decrypted = await _cryptographicImplementation.Decrypt(agentPrivateKey, envelope.Message);
|
||||
|
||||
return JsonSerializer.Deserialize<AgentActionMessage>(decrypted);
|
||||
}
|
||||
|
||||
public async Task<MessageEnvelope> CreateAgentMessage(string agentId, TimeSpan secretValidPeriod, params AgentActionMessageProvider[] providers)
|
||||
{
|
||||
var serverPrivateKey = new byte[0];
|
||||
var agentPublicKey = new byte[0];
|
||||
|
||||
var agentActionMessage = new AgentActionMessage(agentId, secretValidPeriod, providers);
|
||||
var encrypted = await _cryptographicImplementation.Encrypt(agentPublicKey, JsonSerializer.Serialize(agentActionMessage));
|
||||
var signature = await _cryptographicImplementation.Sign(serverPrivateKey, encrypted);
|
||||
|
||||
return new MessageEnvelope(encrypted, signature);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AuthJanitor.KeyProvider
|
||||
{
|
||||
public class GeneratedKeyProvider : IKeyProvider
|
||||
{
|
||||
public Task<byte[]> GetPrivateKey(string keyName)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public Task<byte[]> GetPublicKey(string keyName)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AuthJanitor.KeyProvider
|
||||
{
|
||||
public interface IKeyProvider
|
||||
{
|
||||
Task<byte[]> GetPublicKey(string keyName);
|
||||
Task<byte[]> GetPrivateKey(string keyName);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.6" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.6" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.9" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AuthJanitor.AgentBridges;
|
||||
using AuthJanitor.IdentityServices;
|
||||
using AuthJanitor.Integrations.CryptographicImplementations;
|
||||
using AuthJanitor.Providers;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AuthJanitor
|
||||
{
|
||||
public class PerformProviderWorkflow
|
||||
{
|
||||
private ICryptographicImplementation _cryptographicImplementation;
|
||||
private IIdentityService _identityService;
|
||||
private ProviderManagerService _providerManagerService;
|
||||
|
||||
public PerformProviderWorkflow(
|
||||
ICryptographicImplementation cryptographicImplementation,
|
||||
IIdentityService identityService,
|
||||
ProviderManagerService providerManagerService)
|
||||
{
|
||||
_cryptographicImplementation = cryptographicImplementation;
|
||||
_identityService = identityService;
|
||||
_providerManagerService = providerManagerService;
|
||||
}
|
||||
|
||||
[FunctionName("PerformProviderWorkflow")]
|
||||
public async Task Run(
|
||||
[QueueTrigger("%agent-receive-queue%", Connection = "AuthJanitorAgentBridge")] string agentQueueItem,
|
||||
ILogger log)
|
||||
{
|
||||
// Set "agent-receive-queue" in settings
|
||||
var message = await GetAgentActionMessage(agentQueueItem);
|
||||
|
||||
var logger = new RekeyingAttemptLogger(log);
|
||||
var providers = message.Providers.Select(p => _providerManagerService.GetProviderInstance(p.ProviderType, p.ProviderConfiguration)).ToList();
|
||||
|
||||
var agentCredential = await _identityService.GetAccessTokenForApplicationAsync();
|
||||
if (agentCredential == null || string.IsNullOrEmpty(agentCredential.AccessToken))
|
||||
throw new Exception("Could not acquire access token for Agent application");
|
||||
providers.ForEach(p => p.Credential = agentCredential);
|
||||
|
||||
// todo: relay log output messages to send queue
|
||||
await _providerManagerService.ExecuteRekeyingWorkflow(logger, message.ValidPeriod, providers);
|
||||
}
|
||||
|
||||
private async Task<AgentActionMessage> GetAgentActionMessage(string queueItemContent)
|
||||
{
|
||||
var envelope = JsonConvert.DeserializeObject<MessageEnvelope>(queueItemContent);
|
||||
byte[] ajServicePublicKey = new byte[0]; // get from settings
|
||||
byte[] agentPrivateKey = new byte[0]; // get from settings
|
||||
|
||||
if (await _cryptographicImplementation.Verify(ajServicePublicKey, envelope.Message, envelope.Signature))
|
||||
{
|
||||
var decryptedMessage = await _cryptographicImplementation.Decrypt(agentPrivateKey, envelope.Message);
|
||||
return JsonConvert.DeserializeObject<AgentActionMessage>(decryptedMessage);
|
||||
}
|
||||
throw new Exception("Signature verification failed!");
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче