Handle sql-server permissions gracefully with Navision - sql-server

Background
I am in the process of creating an application (referred to as MyApp) which must read data out from a SQL Server database handled by Navision. Navision users should to be able to use my application, without modifying permissions in the database.
Navision's handling of permissions seems to be on the application layer. It performs the checking of permissions without storing them in the database.
Problem
Navision overwrites users, permissions, and other related objects in the database when synchronizing with the database, so the normal approach of creating a DB user and just using that won't work.
Possible Solution
What I think would be the most appropriate solution is to create a MyApp role in Active-Directory, which grants the necessary permissions on the DB, and add this role to all users.
I do not know how to do this, or even if it's possible. Other solutions, or proposals, are welcome, but please only suggest solutions with can be managed from within ActiveDirectory or Navision.
The server is an SQL Server 2008 server running Navison 5, and the client is Navision 6. I'm using Active Directory for Windows Server 2K8.
EDIT:
My app is a crate creating and designing application. It needs to read out the customers' names and IDs, and a few items in the items table, and that is why I need this functionality

If you use the enhanced security model in NAV, user permissions are synchronized to SQL Server. However, these SQL permissions are mapped to an app role in SQL Server, rather than the user's login. If you use the standard security model, all users map to a single SQL app role which is a super user (less secure).
If you want to access the data in SQL Server using the NAV security model (i.e. through the SQL App roles NAV creates), you should use the CFront API (installed via the SDK option). If you are using NAV 2009 web services are also an option.
If you want to access SQL Server directly, then you will have to manage the permissions yourself using SQL Server. If you create a SQL script to grant permission it is easy to restore anything which NAV might delete during Synchronize Logins.
You can't grant SQL permission from Active Directory exactly as you described. Instead you must map Active Directory groups to either SQL Server logins or NAV Windows Logins (depending on whether you decide to access SQL directly or go through a supported NAV API). Note: the permissions associated with the role are managed in SQL or NAV respectively; not in AD.
From an administration perspective, you can simply add and remove users from this Active Directory group. If you use the NAV enhanced security model each user in the AD group must also have an entry in Windows Logins, and whenever you make changes you must Synchronize Logins. This slight inconvenience is a hangover from the native database.

In general, skipping the NAV layer and reading/writing directly to the DB is not recommended at all as you're bypassing all of NAVs business logic which is stored in the table and report objects in NAV.
What does your app intend to do (broad strokes if you can't get specific) and would using a NAV add-in or dataport be feasible?

Related

PowerApps allow guest users to connect to Azure SQL database with AAD integrated feature

I have a specific problem to which I couldn't find any answer online.
The situation is the following:
We created a Canvas app that connects to the Azure SQL database. We set the connection type to be AAD integrated.
Users that are members of the AD can see the data in the app, but guest users, even though we gave them all the rights and PowerApps plan, cannot see the data. they recieve the same authorization window as members, but when they click on allow, the app starts but no data is being pulled from the SQL database.
When we try to connect directly to the Azure SQL database with the guest user email and credentials (via SQL server management studio), everything works as expected and the guest can see all the tables.
When we use implicitly shared connection (with SQL server authentification), guests can see the data, but we need to use AAD integrated due to its security.
So far we tried:
Changing PA environment from sandbox to production
Adding special permissions in SQL database like database owner etc
Trying out different AAD guest user settings, eq- setting that guest users have the same privileges as members (picture below).
Nothing seems to work. I would be more than happy if you could tell me how to make this work or even push me in the right direction.
I've reproduced your problem in my side. Here's my experience.
After assigning powerapp license(I use O365 E5 here) to guest account and share the app to this account, I can visit the app but can't see the data in the table. I assume that it resulted from the connector hasn't been shared, but it's true that this connector can't be shared because of no 'share button'.
Then I tried to add access policy to my guest account with these two sql:
CREATE USER [tiny-wa_outlook.com#EXT##xx.onmicrosoft.com] FROM EXTERNAL PROVIDER;
GRANT SELECT ON dbo.tinyTest TO [tiny-wa_outlook.com#EXT##xx.onmicrosoft.com];
Pls note here, I used the User Principal Name here(can find the principal name in azure ad->users), I also tested to use 'tiny-wa#outlook.com' in the sql but after executing successfully, it didn't work.
So I think you can try to use the sql above to add your guests accounts and make them can access the powerapp.
Here's some related docs:
create contained users mapped to azure ad identities
Share app resources
add table permission to user
==========================UPDATE==========================
Share my experience of this troubleshot.
First I need to create a power app but I found that after creating the connector with sql server azure ad authentication, it can't connect to the sql server, the error message is like 'Credentials are missing or not valid. inner exception: The credentials provided for the SQL source are invalid', solution is add my admin account as sql server instance Active Directory Admin.
Then I choose a table and successfully create a sample app. With the creating account, I can visit the app but other accounts can't. Here needs to share the app and it's related connectors to other users. But other accounts still can't reach the app because of no license. Because sql server connector is premium connector, so I assign O365 E3 license here. I met an error when assign license, the user's 'Usage location' can't be null or it can't assign license in M365 admin center.
Then I met similar error with Op, the difference is that both member account and guest account can't see the data in app. I try to find the way to share the connector to these uses but failed, I haven't made sure if those connectors without share button can be shared to others. So I have no options to study if this kind of connectors are authenticated in other ways so they don't need to be shared at all.
Next actions is using the account which used to create the sql server and database to sign in database and execute the sqls above.
Then the member account can see data in the power app while the guest account can't see. The reason is I used xx#outlook.com as the parameter in the sql, when I used xx_outlook.com#EXT##xx.onmicrosoft.com, it worked finally.
Hope this can also help you.
===================================================
For creating my demo app: First, I'm sure my environment isn't a sandbox(the environment in the screenshot below). And I think it's easy to create a demo app, and my app is simple, just choose to create an app from data and then select sql server as the connector, next I choose auzre ad auth and click the connector, enter server name and database name then choose a table, after that my app has created. That table has one row of data so when I signed in the app with the creating account, I see it in the screen while other accounts(member or guests) can't.
My sql server instance and database are created long time ago, but I'm sure I followed this tutorial to create them.
This appears to still be a limitation to access to Azure SQL via PA connector for guest users:
https://powerusers.microsoft.com/t5/Power-Apps-Ideas/Azure-SQL-to-PowerApps-Connector-AAD-doesn-t-work-for-guest/idi-p/1637817
If the "guest" does NOT have a PowerApps Per-App/Per-User plan, they cannot use your PowerApps with SQL data source (Note: SQL is a premium connector).
Determine exactly which type of license the guest has. Then, either your organization or the guest (or guest's org) must purchase one of these licenses. $5/$10/$20 per month depending on your use case.
REF

What are good practices for granting database permissions to a web service connection?

I have been searching for articles and SQL script examples that would demonstrate how to securely and conveniently solve one of the most common scenarios - connecting from a .Net Core Entity Framework based web application to an SQL database.
But somehow I could not find any coherent step-by-step guide from a reputable source.
Let's assume the following:
I cannot use integrated Windows auth in the connection string and must use username and password based auth (because hosting on a Linux server and the DB is on a different Windows server)
the web service will need your usual minimum set of permissions - connect to the database, read data, write data, delete data, execute stored procedures
While reading many tutorials, I find there are multiple ways to manage the connection permissions. To avoid this question being too broad, I'll list my current choices as I understand them (please correct me if I'm missing something).
Users and logins:
create a login and a user for the database
create a database-only user without a login (not sure if this is applicable to a web app and connection string, but still it's a feature that I've seen being used)
Assigning permissions:
assign the user to some fixed SQL role (db_datareader, db_datawriter AND also will have to grant EXECUTE permission)
grant all fixed permissions
create a custom role (let's say, db_web_apps) with required permissions
Which choices are better (more secure and easier to manage in general) and recommended by SQL DBAs?
I think every database administrator should have a template script handy for quickly adding a new user with minimum required permissions every time when developers ask for a new connection for their shiny new web app.
If you know a good, reliable tutorial or GitHub / Gist example that explains what and why is being done that way or a script that you yourself have used for years without any issues in production environments, I'll really appreciate if you could share it.
Create a role in the database and assign the required privileges to the role. Don't use the fixed database roles. Instead grant permissions directly to objects, schemas, or the entire database if necessary. Like this:
create role trusted_app_role
grant select, insert, update, delete, execute
on schema::dbo to trusted_app_role
That will grant the role full DML permissions on all the objects in the default dbo schema. So if you have any tables or procedures you don't want the app to have access to, just create them in a different schema, say, admin. This way you never have to fiddle with permissions as you add objects. The fixed database roles predate schema-based permissions, and aren't really needed any more.
For your application's identity, add Active Directory or Azure Active Directory (Azure SQL) identities to this role, or, if you can't, add SQL Users to the role.
If you are on Azure SQL, you should normally use a database user without a login. On SQL Server you can only add "contained database users" if you enable Partial Database Containment. Which you can do, but is incompatible with Change Tracking and Change Data Capture, so it's a tradeoff.
So normally for SQL Server you still create a login and map the user to the login. EG:
create login web_service_user with password = '5X+jeuAB6kmhw85R/AxAg'
create user web_service_user for login web_service_user
And then add that user to your role
alter role trusted_app_role add member web_service_user

Navision 2009 R2: nav users, roles and sql application roles

I see Navision uses SQL application roles to manage user permissions to select, insert, delete data in its tables.
I see that for each navision user, exists a SQL database user with the same name.
Relation between nav roles and sql aplication roles is not direct. It seems there are as many SQL application roles as diferent sets of nav roles are applied to all nav users.
Anyway I guess there is some place where it is stored which SQL application roles each user must use. Do you know where it is stored this info? The SQL application roles names are a litlle criptic... Do they have some meaning?
Well "enhanced" is strange mechanism. As it mentioned here it has a "activation mechanism" for application roles and almost no documentation (even on administrating level).
As far as I understand this is the way it meant to be used: you enable enhanced level and administrating users and their roles in Nav, after that you develop (or use) third-party application that uses Nav data through SQL Server directly (loosing all business logic of course). In this case you can use same user credentials both in Nav and in the application and have same access level to the data (and same restrictions). But this does not mean you can manage permissions outside of Navision. Moreover because of mentioned "activation mechanism" the only place to manage security is classic client.
In case of standard security application user will have SQL-managed set of permissions and Nav user will be restricted by Nav Roles. And be the happiness.
If you are using Database Logins, then the logins are validated against those stored in the database. Windows logins are managed by the domain and a validated in the Active Directory during login. In both cases individual table insert/update/rename/delete permissions are set in NAV under a NAV 'role' (Tools > Security > Roles).
Classic Client
If a user needs access to the classic client, a group or user could be used in SQL to give the dataread, datawrite SQL roles.
Role-tailored Client
NAV 2009 R2 is in the three-tier architecture, so if you're using RTC, you should make sure your service tier account has access to the SQL database, but apart from that permissions for individual users are managed from the Classic Client (Tools > Security).

SQL Server Windows Authentication Security

We have an application that uses Windows authentication to authenticate users with the database, and the SQL Server user accounts need to have certain read/write access to database tables.
The trouble is that the users can then install SQL Server Management Studio and potentially use the database in ways it's not supposed to be used, which isn't what I want.
Everything that I have read says that using integrated authentication is more secure but at the moment, any user can use Management Studio or Access/Excel to just connect to the database.
I have read question SQL Server Authentication or Integrated Security?, which suggests some workarounds, but I don't really have the option of changing the app as drastically as re-factoring all of the stored procedures etc. so I was hoping there might be another option?
Thank you,
NIco
Everything that I have read says that
using integrated authentication is
more secure
--> It's more secure in a way because it's more difficult to get the password.
If you use SQL Server authentication, the connection string contains user and password. If you know where the connection string is (often in a config file), you can open it and see user and password.
On the other hand, if you use Windows authentication, the connection string just says "Integrated Security=True" and you connect to the server with your Windows account, with the actual password buried somewhere deep in Windows' guts and more difficult to retrieve.
Of course, the big downside of Windows authentication is that if your users need write permissions on a certain table for your application, this means that they can write to the same table with ANY other application as well.
There are some workarounds, but none of them is THE silver bullet:
If your app only needs certain tables of the DB, you can just give permissions on these. So at least, the users can't do stuff in all the other tables
If the users are not allowed to access any tables at all from outside your application, there are unfortunately only two things you can do:
Change your app to SQL authentication and remove all permissions for Windows users
(you can also use a proxy service like Will Hughes suggested, but the effect is the same when the app accesses the DB directly...the point is that your users' Windows accounts don't have any permissions anymore!)
Create views and stored procedures (if they don't already exist anyway) for the stuff your app can do with the database. Give the users permissions to use these, and remove the permissions to the real tables.
--> the users can access the views and SPs directly with other tools (even if they don't have any permissions on the underlying tables...permissions on the views and SPs are enough), but they can't do anything that they can't do in your app as well.
If you don't want users to have access to your database, don't grant them access.
If you need to control what they can do - then you should do your access control in a webservice (or some other form of proxy service), which will then execute approved queries, return data, etc.

Is it true that SQL auth is only great for multiple role apps?

I believe Windows auth is the best practice to use to connect to SQL DB. I am hear talking about application user account..
Is it true that SQL auth is only great for multiple role apps and window auth is only good for single role app? I never heard that windows auth with muitple role os only good for smaill internal app?
multiple Windows logins = multiple connections = no pooling = poor scaling?
The problem with using Windows auth for a web application is that many web applications store their application users' credentials in the same SQL database that is used for other application data.
So you have a chicken-and-egg problem. You can't authenticate the user before connecting to the database, and you can't connect to the database without authenticating the user.
It should be possible to use Windows authentication, and then also have application-specific attributes of the user stored inside the database. But most people find this cumbersome to administer, and also limiting to portability of the application.
For example, if one of the feature of the application allows users to change their own password, then the process running your web application needs the privilege to alter a Windows password, which may mean that the application needs to run with Administrator privileges.
If you let the application manage user ID for the context of the application, then to change a user's password is just an SQL operation, and your application is in charge of enforcing security for that.
I'm not sure what you mean by single-role and multi-role app. I have built apps before where there are multiple SQL Server Database Roles, each with a Windows Domain Group of users allowed in that role. So user management is completely within Active Directory, with a 1-1 correspondence between the Domain Group and the Database Role.
We typically did not manage the security within the application itself except obviously declaratively during the database creation where each object was granted access by particular roles according to the design. Typically, in a simple case, we relied on db_datareader role being granted for general usage to non-specific groups of users like database and network administrators for troubleshooting or report-writers or business analysts for ad hoc reporting. Actual users of the app would be granted execute on the relevant SPs to be able to modify any data (so all data creation or modification was through SPs and only explicit members of the ThisAppsUsers AD group could do it). Any advanced SPs (say, merging or deleting accounts) would only be accessible by ThisAppsAdmins AD group. And that was usually all we needed for moderate-sized applications. For more complex functionality, it was also possible to interrogate AD directly for custom attributes (user is an admin only for this customer account but for others is just a user)
This same technique can be used with SQL Server logins, but of course the individual SQL Server logins have to be added to the database roles, and you don't have the richness of AD and have to build some kind of directory service into your database.
The ability to even use AD may not be possible for many applications, so in that case, the security architecture would obviously have to cater to that model.
using the integratedSecurity=true option for SQL JDBC , by including the JDBC auth .dll, should give you database connectivity without authenticating...

Resources