App A is communicating to database X through web service Y. Service Y enables insert, update and delete operations to data in database X. Many authorized people can use app A and connect to database X through service Y.
Developer Q wants to create a database trigger to log some information about the entries and updates on a table in database X including device id or IP. Can developer Q access some device identity through the established connection to database X through service Y?
If he/she can't, is there a workaround?
Short answer yes. The how is a bit more involved. You did not include what language the web service is written in so keeping it high level and focusing on the implementation agnostic way first.
Most languages used to code web services capture request information - device info, web client info, ip address (not reliable though), authentication identification (if not anonymous access), etc. So one typical way to track this data is create a session table in the database that you write all the pertinent request data to for web service session. Then derive a key for each session. Finally add a column for the session key to each table you execute DML on. Alternate approach is to have an operational table (what you already have) and a matching log table. the operational table doesn't have a session key column, but the logging table does. There are other ways to log activity, these are just some to demonstrate the point.
Another way, OO example, is to create a derived connection class that you add in web service session info to. This can then be accessed at the database command execution, usually done via a command object, and instead of writing triggers you programmatically do the logging.
In your particular case, the latter approach seems more appropriate than triggers since triggers could fire when someone does DML on the database directly, or another interface instead of the web service. In which case there would be no request info to begin with.
Related
I only wish to employ Auth0 as my application's API provider but otherwise
would prefer to maintain any and all data about my users within my application's own database, thus, as one might well surmise, my application's database contains a users table along with several related tables. So, once a user signs up for my app, I'd need to create records for that user within the database. Then, once the user logs in via Auth0, I'd like to retrieve that user's data via information contained within the access token. (The field that presents itself as most useful for this purpose is "azp," or "authorized party.")
I'm thinking that, once the user signs up, as part of the effort to create the relevant records within the database, I'd save the "authorized party" value to a field on the users table. (Which field I cannot say, but, for now, this seems as sound a plan as any.) Then, when the user logs in via the Auth0 hosted API, I would retrieve their record from the database via the "authorized party" value.
Does this sound like a reasonable/sound plan? This is my first time building a full-on application from scratch, and, well, this particular detail has me scratching my head.
I'm new to couchDB and still reading tutorials. My question is if it is the normal way to represent every user of my application as a new database user, as it seems to be explained that way everywhere I look?
Let's say I have an online game with many different players - would I create a new "database user" for every player who registers? Or would I make my own database "players" and create a sign-in logic in the app? Not being used to document-driven DB's it seems strange to me not to distinguish between db-users and users of my application...
You could do it either way. First about couchdb users
Users in couchdb are stored in a special _users database
Database permissions are handled by a special _security document. This is specific to every database.
In security documents you add users that you have already stored in the _users database previously.
So you can certainly create a database per user. Before doing that ask yourself if the data that you store in each database is truly independent. Because you can't run map reduce queries across databases. So if you are planning to do aggregation across data for different users then this approach will not work.
Couchdb can also help you with app level authentication. Since couchdb uses a cookie based authentication:
Store your "business logic users" in the special _users database.
Authenticate it with the _session endpoint.
Extract the cookie header and sent it with your application headers.
All the logic for authentication is implemented for you by couchdb. All you have got to do is manipulate headers. Send the cookie from your application and when authenticating with couchdb send it with couchdb's headers.
If you prefer to write entire session management in your application that is fine too. In this case simply store the users in your database and verify that they exist before authenticating them. Like you would do with another database.
The benefit of using couchdb is that it is secure by default --using pbkdf2 encryption scheme to encrypt passwords.
If you instead want to manage all docs using a single database, but still implementing read/write ACLs, you can check the Chatty Couchapp Tutorial app from Smileupps App Store
It's a pure couchapp, relying on CouchDB only as its backend. The tutorial is still work in progress but the couchapp is fully working and you can download its source code.
It implements role/user based read/write ACLs using a single CouchDB database. This way you don't have to setup N replications where N depends on the number of your users. You only have one database containing all your data, easy to be queried on the fly(with temporary views) and for maintenance operations. Of course you can decide to increase the number of database, depending on type of your data and use cases.
A single couchapp contains all the necessary code for frontend, admin dashboard and server side API implementing business rules
The user, depending on his roles have different access to different sections. i.e. he can access the frontend website, but not the admin dashboard.
You can install the free trial, then download the source code with Smileupps deployment tools, change it, upload it back and check your changes.
I am trying to use the new authentication system and I cannot find any decent articles/documentation to get what i want. Plenty of stuff out there explaining how the authentication process works out of the box but realistically you will need more.
First of all how do you control which database you store user information? I have read in many place that you can add a connection string. Ok great, but how do you get that connection string to be used by the authentication system?
And how would this work in a web farm, assuming user account information is split across databases with a little piece of logic which decides which database a user should login against?
I have used keystone extensively and it really isnt bad to implement. Its the authentication mechanism of Openstack. Check it out here http://docs.openstack.org/developer/keystone/
To answer your question users would first authenticate with it, receive a token, then they would present their token at any of your servers. If your data is split up, you can configure keystone to only allow access to certain areas of you backend via groups.
Changing the underlying database needs to steps. You have to add the connection string for the database you want to use for Identity. After this you have to change the base constructor call in your DB context to pass your new connection string to the base class (this is your missing step). An example for it is shown in this thread.
For your second question I don't have a good answer, because I haven't used Identity in a multiple DB servers scenario yet.
We have a Web Role which used to run in a single instance for some time. To cope with higher loads (and to get a better SLA) we're currently migrating the role to support multiple instances.
The role uses Forms Authentication (with a custom membership provider), and our understanding was that we would have to enable some sort of shared session state between the instances, so if a user signs in on instance 1 and gets his .ASPXAUTH cookie, then instance 2 knows about this cookie.
We did that, and currently the role is running on two instances, and everything works well. We tested that a user stays signed in, even if his request is processed on the other instance than the one on which he signed in. If the user doesn't sign in, access is denied.
We also checked whether the TableStorageSessionStateProvider created a table in the Azure Table Storage account, and indeed, there is a table Sessions with PartitionKey, RowKey and Timestamp columns.
But, to our astonishment, the Sessions table always stays empty. No matter how many users are signed in, there is no data in the table.
How can these instances communicate, if not through the Sessions table?
You're mixing up two different things here: Authentication and Session State.
It's true that, in order to use Session State with multiple instances, you need a shared store (InProc won't work). In that case TableStorageSessionStateProvider would work since all instances have access to the session data stored here. Session state is used when you store something in the current session of the user, like a shopping cart. And you would call it like this: Session["UserShoppingCart"] = shoppingCart;.
But what you're describing in your question has nothing to do with the Session State, it's all about Forms Authentication. When you authenticate on instance 1, you'll get a ticket in return (stored in the .ASPXAUTH cookie). This ticket is encrypted and signed and contains basic information like your username, expiration, custom user data, ...
Now that you have multiple instances it could be that the next request lands you on instance 2. And I think your question was, how do the instances communicate? Well, they don't. Whenever the request starts, before it reaches your page or your controller, the FormsAuthenticationHttpModule kicks in and looks for the .ASPXAUTH cookie. It checks the signature, decrypts it and then fills the HttpContext.Current.User with the information from the cookie (the ticket).
The only link between the instances is the machineKey (used for encypting/decrypting/signing/validating the cookie). Whenever you deploy multiple instances in Windows Azure, the Fabric Controller makes sure all instances get the same machineKey. This way, instance 2 will be able to decrypt and validate the ticket encryped and signed by instance 1.
Using a strongly typed dataset and its related table Adapters, normally when I want the changes to pass back, just pass it the table and let it do all the work.
What are some easy ways to enforce security roles on the application user as to which fields they can insert/update/delete when the database is using an application ID instead of user level security?
Do I have to go row by row and check each row against what this particular user is allowed to do (by checking the current version of every field against it's proposed version against their role's permissions?
I believe the first level of security would be locking down the columns on the UI a particular user is not supposed to modify, but what about at the data level? Is there a nice way to do this?
Is this easier in linq-to-sql?
First, are you asking about actual security or just control/saftey/fool-proofing (ie stopping users from doing something dumb)?
If you are trying to enforce security try to answer some questions like who is allowed to connect to the database? where is the actual enforcement (eg, application vs connection to the database)?
For example if your application is where enforcement is placed then what if your application is compromised? Can it then connect to the database and do whatever?
For role separation I would suggest different application that are running/assigned different roles. Each role has to authenticate against the database in some way and only have access to necessary data.
In summary, ask who is doing what to whom and what if they were compromised.