How do I make Roles.ApplicationName threadsafe? - asp.net

I am currently writing a user management application which administers users in a single aspnetdb instance. This single instance contains multiple "applications" which all have roles assigned against the individual applications.
As each user can be a member of multiple applications I use Roles.ApplicationName to cycle through each configured application and then determine which roles they are a member of. After checking each application I set the Roles.ApplicationName back to the original application which is the management application.
The problem I am having is when multiple users eachview an individual application and a request for Roles.GetAllRoles() is made. Most of the time the roles that come back are for the intended application but sometimes the wrong application's roles come back due to other requests cycling over the Roles.ApplicationName per application.
I've since read that Roles.ApplicationName is not threadsafe and therefore should not be used in a web application but I would prefer to have a solution to this rather than having to rewrite the role model in the application.
Also, The aspnetdb applications are created via this administration system and therefore I cannot create multiple RoleProviders, one per application.

Why dont you write a wrapper to do this, off the top of my head you could implement your own role provider, and then put the appropriate synchronization in place.

Related

Will my website assemblies always run in the same AppDomain together?

I have built two different user control libraries to use on my SharePoint 2007 site. One provides user controls for Ecommerce functions, the other for an account dashboard. Both of them are make use of authenticated users/site membership.
So I've built an assembly called WebAccounts.dll which contains all of the basic, common, account functionality such as logging in, logging out, retrieving member data and storing certain pieces of member data in session. Both the Ecommerce library and account dashboard library reference this account and build on top of it. For instance, both provide their own version of a login/logout control that captures the user credentials, and pass them along to WebAccounts to be authenticated and store the authenticated member object in session.
Where I'm lost is ultimately how IIS creates AppDomains and instances of these libraries. If I place all 3 assemblies in the bin of my SharePoint site, is a user guaranteed to be using instances of the three assemblies contained within the same AppDomain? Or on one page might a user's request process in an AppDomain where only Ecommerce and WebAccounts is loaded, and the next request process in an AppDomain where only dashboard and WebAccounts is loaded?
Point in case: I would like WebAccounts to provide Login and Logout events so that anything that uses the assemblies can perform server-side actions in response. I.E. Can a user be using Ecommerce, which adds some objects to Session State, then click "log out" on a Dashboard user control, which in turn calls Logout() in WebAccounts.dll, fire a "LoggedOut" event in WebAccounts.dll, and be guaranteed the instance of Ecommerce I was using (which has subscribed to the event on application startup) will be able to handle that event to remove its items from Session State? Another example is if WebAccounts defines a static variable, will Ecommerce and Dashboard use that same variable as I navigate between the pages of the site? Since these all run under the same application starting point, the SharePoint site, in the same bin together, it seems like they should all be in the same AppDomain and it should work?
Other concerns are the GAC, and scalability. First, my assemblies are actually in the GAC, because it's a lot easier to use them in SharePoint that way. My expectation would be that loading them from the GAC instead of the bin wouldn't change the way AppDomains are set up. Second, if we were to move to a server farm, could it still work. Given than we're using SQL based session state, I think that part would work. I know accessing a static variable would break down from request to request because there would be multiple instances of the variable on different servers, but could the variable be reliably set and retrieved by both user control libraries during a single request? Was my WebAccounts assembly just a horrible idea for a web site?
During normal operations there is one worker process and one app domain for each web site (assuming you are using one web site per app pool - I'm not aware of any reason of not doing that).
This means that all code that is loaded will share the same static variables and the same application state.
During recycling there can be multiple workers and multiple app domains but their contents are structured in the same way.
I don't know how Sharepoint operates. Probably, it runs as a single web site. Therefore, all code that is loaded is hosted in the same app domain.
The litmus test to see whether two libraries share the same app domain is whether they have access to the same HttpContext.Current.
The GAC does not play any role here. There is no such thing as "an instance of a DLL". There is just one DLL and it can be loaded into different app domains.
I know accessing a static variable would break down from request to request because there would be multiple instances of the variable on different servers
That is true.
but could the variable be reliably set and retrieved by both user control libraries during a single request
During a single request there is only ever one app domain involved in processing it. No exceptions. Whatever code is loaded in that app domain can take part. So as long as Sharepoint decides to load your code (and call it) you're set.
I would like WebAccounts to provide Login and Logout events so that anything that uses the assemblies can perform server-side actions in response.
The key question is: Is there anything that causes your DLLs to hook up those events? Ensure that that is the case. It is not a concern whether your DLLs are loaded or where. The concern is whether code in them is being called to allow them to subscribe to those events.

managing and restricting roles without the use of membership

I have a web application which requires two types of users, well 3 but the third one doesn't require a role: Admins which can access every page including the admin page which allows control over members; Members which can access every page except the admin page and they can post their data (high scores of a game); and guests which can visit all pages except the admin page and they can't do anything really.
Looking around I found out that ASP.NET has roles but they are tied to only three types of role providers(SqlRoleProvider, WindowsTokenRoleProvider, and AuthorizationStoreRoleProvider). Also I'm unsure but I assume that ASP.NET's Roles are connected to the whole Membership thing which means that unless I use the ASPNETDB.mdb database everything fails.
Anyway I have to restrict everyone but the admins from entrance to the admin page and allow members to post their scores. The idea I have now is that upon login, when I authenticate the user I store the user role into the cookiless session data and read it on every page load and proceed accordingly. Is there a better way?
Asp.net membership is not tied to a DB, you can roll your own, but I am assuming that you will be storing your users in a database of some sort, so the SqlProfileProvider is probably sufficent (this can be any database, does not need to be ASPNETDB.mdb).
Details on adding this support to existing DB is here: Create ASP.Net membership database structure in existing database
You will need something like the membership, as you will need to login, you need roles, and this is what the membership API is all about. It also uses industry standard storage etc., so that you don't code yourself a security hole by rolling it yourself.
You can then restrict either individual pages, or more commonly entire folders (e.g. an admin folder) by role using web.config files.
Well, it doesn't really matter how you call your database as long as you register the membership and roles services in your own database. It is as simple as running the aspnet_regsql command prompt tool without any parameters whatsoever and it will launch a wizard (.net style) to guide you through the installation of these services. ALL it does is create sql server objects in the database you wish (schemas, tables, sprocs, etc)
Now, if you dont like these built in providers (particularly I don't) there's nothing stopping you from implementing your own, it's quite simple but maybe a lengthy process due to the amount of abstract or virtual methods you'll need to implement/override depending on your approach or need. You two options to implement your own...
one is implementing theRoleProvider abstract abstract class or
extend/inherit from the SqlRoleProvider class which exposes a lot of virtual methods and properties.

How asp.net single web page(aspx) is processed for multiple user

I need complete information about how aspx single page server multiple users as compared to stand alone window application where separate exe is running on each user machine.But how exactly single aspx page serve multiple users at same time.
I search on Google but not get any good example.
I need any article or reference link for understanding the same.
Every request to any ASPX page will create a separate instance of the page class, generally all in the same AppDomain.
There is no concept of a "user", although you can create one using cookies or session state.
Choosing Between Windows Forms and Web Forms
Programming model
Windows Forms is based on a client-side, Win32 message-pump mode,
where instances of components are created, used, and discarded by the
developer.
Web Forms relies on a largely asynchronous, disconnected model, where
components are loosely coupled to the application front end.
Typically, application components are invoked through HTTP. This model
may not be suitable for applications requiring extreme throughput from
the user end or for those with high-volume transactions. Similarly,
Web Forms applications may not be suitable for database applications
that require high levels of concurrency control (for example,
pessimistic locking).
Security
Windows Forms uses permissions in its implementation of code access
security to protect computer resources and sensitive information. This
allows careful exposure of functionality, while retaining security.
For instance, the Printing Permission, which at one level would allow
printing to the default printer only, at another level would allow
printing to any printer. Using ClickOnce, developers can easily
configure which permissions their applications should and should not
demand from the client. For more information, see ClickOnce Deployment
and Security.
Authorization to gain access to the resources of a Web application is
typically controlled on a per-URL basis by authenticating the
credentials (for example, a name/password pair) of the requestor. Web
Forms allows the developer to control the identity under which server
application code is executed. Applications can execute code with the
identity of the requesting entity, which is known as impersonation.
Applications can also dynamically tailor content based on the
requestor's identity or role. For example, a manager could receive
access to a site, or a higher level of content than someone with lower
permissions.

asp.net application with windows authentication and custom membership provider advice

I’ve been asked to upgrade a few applications and I’m planning on merging all of them into one asp.net application. I’m fine with this decision and have spoken with fellow workers and they also think it’s the best option to go with.
The application will be accessed from a small group of users which belong to a larger domain. I’m currently planning on using Windows authentication and only allow this small set of users to access the asp.net application. Also there must be some role management, so that only certain users can view certain functionality.
I really don’t want to have many different windows groups; so I want to avoid having to assign different windows groups to different folders and control permissions in the web.config.
What I’d like to do is:
- Assign one windows group to the small group of users who will access the page.
- Create a custom membership provider and control the user who accesses the application. Depending on the user I will then assign his current set of roles.
- Add an application setting to the web.config, with the name of the current administrator, so if he logs in, he will be assigned all roles, and will be able to create and assign roles to other users.
I’d appreciate some advice if this would be the correct way to go about this.
Thanks!
I would check out the AccountManagement Namespace.
I like to use this. You can create a global security group (one for each 'role'). The account management namespace will allow you to fetch the UserPrincipal from AD with their logon name from the http context. Then you can check them for memebership in the security groups you created using the .IsMemberOf Method.

What is the best practice for role security for an Intratnet ASP.NET/SQL2K5 environment?

Our current Intranet environment is a little outdated. The current stack has ASP.NET 1.1/2.0 applications that are querying against a SQL 2000 database.
For role security, there are user groups on the servers that users are added into (so you need to be added into the group on the test and production machine). These user groups are synchronized into user roles on SQL 2000 itself. Roles are granted execute permissions to stored procedures as needed to prevent any access violations.
At the web application level, we use basic authentication (which authenticates against our Active Directory) and have identity impersonation turned on. The connection string to the database uses Integrated Security. This creates an environment where the web application connects to the database as the user logged in, which will enforce database security on stored procedures being called. It also allows us to use the typical User.IsInRole() method to perform authorization within the application itself.
There are several problems with this. The first is that only our server administrators have access to the user groups on the machine, so updating role security, or adding additional users is out of the hands of the application administrators. In addition, the only way to get the role was to call a SQL procedure called "xp_logininfo" which is locked down in SQL 2005. While I don't know the full details, our DBA tells us that this general model doesn't play nice with SQL 2005 given the nature of schemas in the newer version.
We're at the point now that we're ready to update our environment. We're writing .NET 3.5 apps to leverage more AJAX and SQL Server 2005 is the primary environment for our database. We're looking to update the security model as well to be a bit more flexible for the application administrators, and potentially leverage Active Directory more.
One concern we have as well is that a given user will most likely have access to multiple applications, so having some kind of centralized solution is optimal so we can easily remove users when needed.
What is considered the best practice for maintaining role security in this kind of environment?
ASP.NET 2.0's Membership, Roles, and Profile
I don't think the considerations related to the decisions that where made before has changed that much.
About the schema comment, those will just help you organize the database elements, so you can assign permissions to all inside a schema instead of having to configure for each procedure/table.
The decisions involved on whether having the identity flow down to the SQL Server instead of using the trusted subsytem model, are pretty much specific to the particular scenario. That said, I don't like to flow identity like that, because usually there is still logic being enforced on the application which means the sp are probably enforcing partial rules. Because of that reason, that approach also pushes to have more logic in the stored procedures.
About only administrators having access to the user groups in the machine, consider looking at ADAM (active directory application mode). I don't know if it supports integrating it with SQL Server, so I am not sure if that will work with that architecture. It is worth checking though.
Regarding not being able to get the roles, based on your info, I would assume there is a close relation between user groups and involved database roles. You can get the groups(roles) the user has in active directory.
Bottom line: evaluate how ADAM fits in your scenario, and whether the considerations involved into using the current identity flow approach remain. Also don't forget to consider the impact in the project on changing the identity flow of the application.
Try to refactor your design in such a way that your repository itself is LDAP. So essentially your users and roles objects map AD objects. You can then have the complete control rather than going through various system administrators. Of course, this is not easy depending on the state of code. But the best way to start out is to create small proof of concept to accomplish this mapping of your business objects to AD.

Resources