EF Core with SQL Server persistence requires VIEW SERVER STATE permissions? - entity-framework-core

If I use EF Core against SQL Server, and the user account on the connection does not have permissions for VIEW SERVER STATE on object 'server', database 'master', the operation will fail with a DBUpdateException stating that this permission is missing.
What is EF Core trying to do that requires this permission? Is there any way for me to disable whatever it is doing that requires it? or do I have to add this permission?

Check if there is any access to the tables like sys.dm_tran_active_transactions, sys.dm_tran_current_transaction when you do the save changes in EF. Maybe it could be through a table trigger. I faced a similar issue due to a trigger trying to access those sys tables.

Related

Notify Blazor + EF Core server when a db table is externallly changed?

I have a EF Core + Blazor client/server application where a table in an sql database may be updated by an external service. The server keeps a copy of that table and should react to changes to the original table (the application needs a copy for reasons). The external service may add, delete or modify records or even write the entire table from scratch, dropping the old table in the process.
Is there a way to have the server be notified whenever that external table is changed, similar to a DB trigger? Or is there a way to have a DB trigger notify the server so that I can process the notification in code in the server?

Staging environment for Azure Mobile Services using Code First Migrations

I seem to have trouble understanding a concept with Azure Mobile Services that are using .NET backend with Code First and migrations enabled.
Currently I have deployed a "productive" instance of AMS, let's say it's called "AMD". It is running at amd.azure-mobile.net. Database structure has been created using Enable-Migrations and Add-Migration. This is all fine now for this productive instance, it is running and is fully functional.
Now I want to create an INT instance to have a separate environment for tests etc. I want to name it differently, say "AMDINT". It should run at amdint.azure-mobile.net and should also have a separate database, to make it impossible to break stuff in production.
Originally I thought I could pull it off like this:
1) Create the new instance under amdint.azure-mobile.net with a new database to go with it
2) Create a web.config transform for a newly created configuration called "INT" (primarily to change the MS_MobileServiceName value to the new name)
3) Download the publishing profile of the new instance, import it, make it use the "INT" configuration and deploy it
The new bits apparently get deployed, but whenever I hit an endpoint that requires DB access, an error will be generated in the logs and it says
Database initialization failed. Could not initialize one or more objects in schema 'amdint'. Please ensure that the database connection string is correct. For more details on the error, please see the inner exception. ---> System.InvalidOperationException: Database initialization failed. Could not initialize one or more objects in schema 'amdint'. Please ensure that the database connection string is correct. For more details on the error, please see the inner exception. ---> System.Data.SqlClient.SqlException: User does not have permission to perform this action.
So I used Azure User Management Console (AUMC) to see if permissions were missing for the user that is being specified in the connection string in the configuration tab of the new service, but the user was present for that database. I also edited the user's permissions to include every possible right, but this did not change anything.
Then I noticed that the migrations files specify a database schema for the Up() and Down() methods. For a test, I changed these strings from "amd.tablename" to "amdint.tablename" and was pretty confident I had nailed it.
However, this still brought the same error. So I used the database user's credentials from the connection string and opened database editor from the management console in the browser, and saw that with all the added rights it can edit the database schema just fine (created and deleted a table for testing purposes). However, no single table has been created by the Initializer; the database was blank.
But since I was able to edit, I somehow believe that either the error message about insufficient permissions is misleading or that I am looking at the wrong place.
Does anyone know of a way to accomplish what I am trying to do? I don't want to have separate Visual Studio projects for production and INT, obviously.
I think what you're running into is the issue that Mobile Services creates a special schema user that has rights to only tables in that schema. This schema has the same name as your mobile service. So, even if the two databases are on the same DB server, the connection string for a DEV mobile service wouldn't work for PROD, and vice versa.
Here are some suggestions to make your setup easier:
In the Azure Portal, Mobile Services doesn't allow modifying the connection string that it creates for you, which is called MS_TableConnectionString. I recommend that in your case, you create a new connection string with a different key and use that for each of your services, e.g., AMD_TableConnectionString. Make sure that for each service, the database user has access to each schema (more on that in a minute).
To use the new connection string, change your super constructor call in your DbContext class, e.g., base("name=AMD_TableConnectionString").
Use the application setting MS_MobileServiceName in your web.config and/or the Azure Portal to set the schema for your service. This is use by the Mobile Service Entity Framework initializer.
NOTE: If you're already using separate databases for DEV and PROD, you have the option of using the same schema name for both your DEV and PROD instances, which might make testing and setup easier.
Either way, the database user in the connection string must have full permissions to whatever schema name you specify in MS_MobileServiceName.
(You probably have this part working.) Make sure that the Mobile Services SQL Generator is run. It will automatically run if you set an Entity Framework database initializer, but some folks like to have all database changes done through DB migrations. In that case, follow this tutorial here: https://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-how-to-use-code-first-migrations/#using-code-first-migrations-without-an-initializer

Is it safe to enable MSDTC (Microsoft Distributed Transaction Coordinator) on our server

I'm always worried about using two instances of DbContext that would require distributed transaction coordinator, especially when I'm using a library like SimpleMembership which has its own connection to the database.
This problem is always an issue in my case. For example I'm using SimpleMembership provider for my application's user accounts and I want to save a user with additional information, like company. So without MSDTC enable I can't do this inside a transaction. So it is possible that inconsistent data is inserted into the database.
So my question is should I worry about this problem and try to find a better solution or I can just enable MSDTC on my server and don't worry about it? Is there any consequences of enabling MSTDC ?
Thanks!

Getting the signed in user in .Net from a Postgresql database

I'm developing a system using NHibernate and PostgreSQL, with Npgsql data provider.
I need to get the logged in user in my system in a trigger in order to run an audit function.
Is there any way to set the user in the NHibernate session or to get it directly from the database?
Please help!
Here's a detailed explanation of how to get application-level user identity into triggers that I wrote a while ago. Essentially you can use a temporary table to store the user login or a custom GUC. Either way, your application must explicitly set that up when it creates a session so that it can be accessed later.
Personally I think you should usually be using PostgreSQL users and SET ROLE as explained here, but I realise that's not always an option.

Is there a way of connecting to shared OpenEdge RDBMS with read only access?

Our new security policies require data access restriction for developers to the production database. Setting up -RO parameter does not work for several reasons (extracts from 'Startup command and Parameter reference' http://documentation.progress.com/output/OpenEdge102b/pdfs/dpspr/dpspr.pdf)
1) "If you use the -RO parameter when other users are updating the database, you might see invalid data, such as stale data or index entries pointing to records that have been deleted."
2) "A read-only session is essentially a single-user session. Read-only users do not share database resources (database buffers, lock table, index cursors)."
3) "When a read-only session starts, it does not check for the existence of a lock file for the database. Furthermore, a read-only user opens the database file, but not the log or before-image files.
Therefore, read-only user activity does not appear in the log file."
We would like to be able to access data on the production database from OpenEdge Architect, but not being able to edit data. Is it possible?
In most security conscious companies developers are not allowed to access production. Period. Full stop.
One thing that you could do as a compromise... if the need is to occasionally query data you could give them access to a replicated database via OpenEdge Replication Plus. This is a read-only db connection without the drawbacks of -RO. It is real-time, up to date and access is separately controlled -- you could, for instance, put the replicated db on a different server that is on a different subnet.
The short answer is no, they can't access it directly and read-only.
If you have an appserver, you could write some code which would provide a level of dynamic RO data access via appserver or webservice calls.
The other question I'd have is - what are your developers doing accessing the production database? That should be a big no-no.