Hub inheritance in Signalr in ASP.NET Framework - signalr

I'm using signalR to build a real-time website.
I have 2 hub:
NotificationHubCore
NotificationHub (inherits NotificationHubCore)
My solution includes 2 small projects : Domain & Web.
I put NotificationHubCore in Domain, NotificationHub in Web.
Now, in the web section, I want to acess NotificationHubCore by using :
GlobalHost.ConnectionManager.GetHubContext<NotificationHubCore>();
It always returns null to me.
My question is : how can I access to NotificationHubCore through NotificationHub.
I've tried:
var notificationHub = new NotificationHub();
GlobalHost.DependencyResolver.Register(typeof(NotificationHubCore), () => notificationHub);
But that way didn't work.
Can anyone help me please?
Thank you,

You may use SQL Server to distribute messages across a SignalR application that is deployed in two separate applications.
Create a new database for the backplane to use. You can give the database any name. You don’t need to create any tables in the database; the backplane will create the necessary tables.
Refer this article and section "Scaleout with SQL Server" for further details - why SignalR

Related

On-prem ASP.NET Framework web app with Azure Key Vault

We're in the process of trying to secure our application secrets in our internal ASP.NET Framework web applications. The initial plan offered to me was to use Azure Key Vault. I began development work using my Visual Studio Enterprise subscription, and that seems to work fine, locally.
We've created a second Key Vault in our company's production environment, and again, I can use it locally, because my own AAD account has access to the vault. However, in this project (4.7.2 Web Forms web application), I don't see any means of specifying the Access Policy principal that we've created for the application.
My google-fu is failing me: is there any documentation that explains how to do this? Is this scenario -- an on-prem, ASP.NET Framework app outside of the Azure environment, accessing Key Vault for confiugation values -- even possible?
Thanks.
UPDATE: I was unable to find a solution that would allow me to use the Access Policy principal from within the "Add Connected Service" dialog. I'm somewhat surprised it's not in there, or is hidden enough to elude me. So I ended up writing my own Key Vault Secret-Reader function, similar to the marked answer. Hope this helps someone...
In this scenario, your option is to use the service principal to access the keyvault, please follow the steps below, my sample get the secret from the keyvault.
1.Register an application with Azure AD and create a service principal.
2.Get values for signing in and create a new application secret.
3.Navigate to the keyvault in the portal -> Access policies -> add the correct secret permission for the service principal.
4.Then use the code below, replace the <client-id>, <tenant-id>, <client-secret> with the values got before.
using System;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
namespace test1
{
class Program
{
static void Main(string[] args)
{
var azureServiceTokenProvider = new AzureServiceTokenProvider("RunAs=App;AppId=<client-id>;TenantId=<tenant-id>;AppKey=<client-secret>");
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secret = kv.GetSecretAsync("https://keyvaultname.vault.azure.net/", "mySecret123").GetAwaiter().GetResult();
Console.WriteLine(secret);
}
}
}

Data Protection using Entity Framework Core

So I have followed microsoft's official guide (https://learn.microsoft.com/el-gr/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-2.2&tabs=visual-studio) for encrypting data and storing them in database using Entity Framework Core, but I can't make it work accross multiple machines. So I used Entity Framework Core implementation because in the guide says "With this package, keys can be shared across multiple instances of a web app.". The app works perfectly when using it from the deployed version for example xyz.com, but It doesn't let me interfere from localhost. Will it be a problem afterwards when my virtual machine is maxed out and I want to add another one? If so how can I make it work in both the deployed site and different machines? There is no tutorial which implements that, I have searched everywhere. Thank you very much.
services.AddDataProtection()
.UseCryptographicAlgorithms(
new AuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,
}
).PersistKeysToDbContext<DataContext>();
Update 12-6-2019
So I followed microsoft's documentation (https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-encryption-at-rest?view=aspnetcore-2.2)
and it states:
"If the app is spread across multiple machines, it may be convenient to distribute a shared X.509 certificate across the machines and configure the hosted apps to use the certificate for encryption of keys at rest"
I generated a x.509 certificate using this tutorial:
(https://www.youtube.com/watch?v=1xtBkukWiek)
My updated code:
services.AddDataProtection()
.UseCryptographicAlgorithms(
new AuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,
}
)
// )
.ProtectKeysWithCertificate(new X509Certificate2("wibit-test-cert.pfx", "password"))
.PersistKeysToDbContext<DataContext>();
When testing on my local machine it works fine, but when I deploy it, I get this error:
error: "The system cannot find the file specified"
I have tried several ways to fix it including _hostingEnvironment.ContentRootPath or WebRootPath. Both these ways and the one I use in the updated code work in my machine but not in the deployed app.
Any clues?
I finally fixed it!
The problem was that I didn't set the application name:
.SetApplicationName("myapp")
And I changed the path of the certificate to this:
.ProtectKeysWithCertificate(new X509Certificate2(Path.Combine(_hostingEnvironment.ContentRootPath,"wibit-test-cert.pfx"), "password"))
Also it may be a permission problem, because when I hosted the app in A2Hosting it could't find the file specified(wibit-test-cert.pfx), but when I deployed in GCP Cloud it worked!
Now I can encrypt and decrypt data using the same database with different apps.
So my final code is this:
services.AddDataProtection()
.UseCryptographicAlgorithms(
new AuthenticatedEncryptorConfiguration()
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,
}
)
.SetApplicationName("myapp")
.ProtectKeysWithCertificate(new X509Certificate2(Path.Combine(_hostingEnvironment.ContentRootPath,"wibit-test-cert.pfx"), "password"))
.PersistKeysToDbContext<DataContext>();

NotificationHub Push Notification returns : The Token obtained from the Token Provider is wrong

I have Wp8.1 Silverlight app that receives push notification (WNS) from Mobileservice (the old azure service).
I therefore wanted to update to the new service because of the new features. I have now created/upgraded a new server to use App Service - Mobile App. And tested push notification with the sample app from azure (everything works).
Going back to my app WP8.1 -> Adding the new package Microsoft.Azure.Mobile.Client through NuGet (2.0.1), there is the issue that the Microsoft.WindowsAzure.Mobile.Ext does not contain the 'GetPush' extension. It seems like it is missing it? looking to the WP8 version, it only registers to MPNS, and I need WNS. So I do not know if any other assembly could be used.
Can I add another assembly reference?
Update
The following code lets me register the device on the server, and I can see the device register correctly. where the channelUri and the installationInformation are retrieved by the client and send to the server.
Installation ins = new Installation();
ins.Platform = NotificationPlatform.Wns;
ins.PushChannel = uTagAndChan.ChannelUri;
ins.Tags = uTagAndChan.Tags;
ins.InstallationId = uTagAndChan.installationInformation;
await hubClient.CreateOrUpdateInstallationAsync(ins);
Sending a test toast-notification to the registered tags, results in the following error :
The Token obtained from the Token Provider is wrong
Searching on this issue I found Windows Store App Push Notifications via Azure Service Bus. Which the proposed solution says to register to the notification hub directly from the app, I would rather not have the app to have directly access to the hub. But is this the only way? (mind you the answer was not accepted, but I will try it all though it is not a desired solution)
Update
Registering for notifications via client (WP8.1 Silverligt), makes a registration to MPNS, which I do not want.
The snippet on the server registers a WNS, the two registrations can be seen here:
The URI retrieval is done using
var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
which in the description states it returns a WNS. This seems to infer that the registration I am doing on the server (code snippet in the top) is correct and the registration on the client is faulty.
But the registration on the image seems wrong. Shouldn't the PNS Identifier be different for the two registrations? also expiration date seems wrong ?
How to mend this since the GetPush() (which was available in the sample registered the client correctly for notifications) does not exist in the NuGet package?
Update
I read one place that deleting and recreating the NotificationHub could help. I will try this today. Even IF it works, it would be more desirable to have the solution, and to know if the registrations are done correctly?
Temporary solution:
Deltede, recreated, inserted Package SID and Secret. And it works again (strange)!
Still interested in the underlying issue!
Deleted and recreated the service, setting all the same settings made it work again.
I had same issue with my UWP. But in my case I had issue with self signed certificate.
When I set the AppxPackageSigningEnabled property to True (in .csproj) then notifications stopped working and I got "The token obtained from the Token Provider is wrong" (Test send from Azure Portal).
The certificate must have same issuer as Publisher in Identity element in .appxmanifest file.

Programming a Web Portal for Microsoft Dynamics CRM

I'm working on a web portal for customers that will connect to Microsoft Dynamics. I don't want to make Dynamics CRM directly a internet facing deployment (IFD), so I'd like to use a separate database that the web interface interacts with and then use web services to move the data between the web portal database and Dynamics CRM.
I'm just looking for thoughts on whether this is the best way to proceed and whether there are any good code examples, etc. that I can look at for implementing this?
I saw Microsoft has a Customer Portal but it looks like it requires (at a cursory glance) an IFD deployment - which I don't want.
First, after creating your ASP.NET project (WebForms or MVC 3), add the following references:
Microsoft.crm.sdk.proxy.
Microsoft.xrm.sdk.
System.Runtime. Serialization.
System.ServiceModel.
In your code-behind Create a class then add the following code:
private IOrganizationService GetCrmService(string userName, string password, string domain, Uri serviceUri)
{
OrganizationServiceProxy _serviceProxy;
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = new System.Net.NetworkCredential(userName, password, domain);
//credentials.UserName.UserName = userName; // uncomment in case you want to impersonate
//credentials.UserName.Password = password;
ClientCredentials deviceCredentials = new ClientCredentials();
using (_serviceProxy = new OrganizationServiceProxy(serviceUri,
null,
credentials,
deviceCredentials))
{
_serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
return (IOrganizationService)_serviceProxy;
}
}
If you want to retrieve multiple records:
string fetch = #"My Fetch goes here";
EntityCollection records = getCrmService().RetrieveMultiple(new FetchExpression(fetch));
I highly recommend to download the SDK or check this
You'll find many samples and walkthroughs which will help you to build good portals.
I think it's a good strategy because:
It allows you to asynchronously put the data entered on the website into the CRM. This decoupling ensures neither the CRM nor the Website will become eachother's bottleneck.
Only the intermediate service layer is internet facing, so you'll be in control over what CRM information would be disclosed/open for alteration if this service layer is compromised.
The architecture you're after is reminiscent of the way the CRM Asynchronous Service works (asynchronous plugins and workflows work this way).:
A job is put in a queue (table) in the CRM DB.
A scheduled service awakes every x seconds and fetches the latest y records from the queue table.
The service performs each job and writes the result (success, error message log) back to the queue table's records.
So the thing that is probably hardest is writing a good scheduled service that never throws an exception (but always digests it) and properly logs the results back to the DB.
To learn more about the Dynamics CRM's "Asynchronous Service Architecture", refer to the following: http://msdn.microsoft.com/en-us/library/gg334554.aspx
It looks like a good approach.
It will improve the performance of both the portal and CRM.
The data shown on portal is NEARLY realtime. i.e it is NOT realtime.
Throughout the development, you better keep checking that there is not TOO MUCH async processing to keep the CRM server busy all time.
I don't think, that the accelerators/portals REQUIRE CRM to be an IFD instance, I guess only the portal part needs to be Internate facing (of course to make it usable for the purpose!)
Anwar is right, SDK is a good lauchpad for such research.
Customer Portal Does not require IFD deployment. And if you do not like the Customer Portal you can always use SDK Extension for Portal development (microsoft.xrm.client.dll & microsoft.xrm.portal.dll and portalbase solution) which are all included in SDK.
There is a great resource regarding how to build portal by using SDK Portal Extenstion.
Dynamics CRM 2011 Portal Development

Multi-Tenant in windows azure asp.net MVC2

Anyone knows how can i start to develop a multitenant site in MVC2, in a way it run on Windows Azure?
I search a lot about this question, and i allways find theoric explanations, everybody says it can be easily done, but i dont find any sample...
Can someone explain me where to start?
Thanks,
João
It depends on how you plan on implementing multitenancy (eg. using authorization with common urls, subdomains, custom domains, or any combination). But you should be able to do just about any approach with Azure and MVC2. If you plan on using a custom domain for each tenant, versus a subdomain, you will need to be happy with using CNAME entries (not A records) to point each custom domain to Azure but that usually is not a problem.
MVC offers many extension points where you can implement multitenancy in its various flavors. The main goal is to uniquely identify the user by either a login or the url.
We have an MVC2 application running in Azure that parses the request url to differentiate the tenant. There are many ways to do this. We took the approach of extending the Controller class to provide our app with the unique tenant information so we could use it as needed to make appropriate repository calls to display the proper views etc.
Here is a sample of what a MultiTenant Controller might look like:
public class MultiTenantController : Controller {
public string TenantCode { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
TenantCode = GetTenantCode(filterContext.HttpContext.Request);
}
private string GetTenantCode(System.Web.HttpRequestBase request) {
string host = new RequestParser(request.Url.AbsoluteUri).Host;
return _tenantService.GetTenantCodeByHostAddress(host);
}
}
NOTES:
The RequestParser function
above is just any implementation
that knows how to parse urls in a
safe manner.
_tenantService
can access some kind of persistent
store (Azure Tables in our case) to
get the TenantCode from the host
address in the url.
All of your controllers would inherit from the above class. Then, to differentiate between tenants you just refer to the TenantCode within your controller like so:
public class HomeController : MultiTenantController {
...
public ViewResult Index() {
var vm = _homeService.GetHomePageViewModelForTenant(TenantCode);
return View(vm);
}
}
Using the above implementation you could serve different sites or data to urls like the following:
http://subtenant1.yourdomain.com
http://subtenant2.yourdomain.com
http://www.customtenantdomain.com
Your backend store (eg. Table Storage) just needs to cross reference host names with the tenant like the table below. In the code above GetTenantCode would access the data.
HostName TenantCode
---------------------- --------------
subtenant1 Tenant1ID
subtenant2 Tenant2ID
www.customtenantdomain Tenant3ID
For www.customtenantdomain.com to work, the tenant needs a CNAME entry for www in their DNS records for customtenantdomain.com that points to your Azure Web Role's address.
Its hugely complex and not something to be taken on lightly. However take a look at the source code for Microsoft's Orchard project. This has full multi-tenancy capabilities if thats what you need: http://orchard.codeplex.com/
And they have a build that works in Azure too.
In this guide we cover aspects of this and it includes a full sample using MVC 2.
link text
First , all answers are very very helpful.It's changing your decision what you want setting up your multitenancy.I mean the most important thing is Identifying all tenant in your app so there is a lot of way for solution.For example you can hold your tenant via subdomains or URL surfing.And also maybe you can store your data multitenat database.
There are very very helpul posts are written by Steve Morgan.
I only help you for set startup multi- tenancy.Here are the blogs :
Identifying the Tenant in Multi-Tenant Azure Applications - Part 1
Identifying the Tenant in Multi-Tenant Azure Applications - Part 2
Identifying the Tenant in Multi-Tenant Azure Applications - Part 3
And here are the Multi-Tenant Data Strategies for Windows Azure :
Multi-Tenant Data Strategies for Windows Azure – Part 1
Multi-Tenant Data Strategies for Windows Azure – Part 2

Resources