'Hi --
I'm changing the way I build my UI from this:
If ( role == 'Admin' ) myComp.visible = false;
...to a totally dynamic UI based on what is returned from the DB. I'm architecting the best approach to this now.
I've read about role-based access control and understand that it's best that the server generates the UI after a user is authenticated, but apart from re-doing the entire backend to store MXML et al., is there a better approach?
Is it a bad idea to have a Permissions object that has properties like:
showTabOne:Boolean = true;
allUserToEditGrids:Boolean = false;
The components visibility and includeInLayout properties will be bound to these values.
The UI will also allow a user to create new roles and set permissions.
The only drawback I see is that every time a new feature is added, the app will have to be recompiled to update the bindings.
Any tips are greatly appreciated.
Thank you!
Permission object is fine, if you have complex enough policy, it is natural to abstract it into its own class. About recompilation - bindings can be set in runtime (BindingUtils), maybe you can use it to avoid it. Not sure what is
re-doing the entire backend to store
MXML
Normal way would be MXML controls composed after the authentification, indeed.
Be advised that someone can spoof a feed or flashvar to create a permission object to get themselves the credentials they require in a client app, allowing them to view/edit supposedly restricted content/areas.
A good approach for this would be, upon server authentication of the user and role, return a manifest xml defining what part of the ui is visible to the user and bind to those properties.
You can take security one step further and put restricted areas in flex modules to be loaded at runtime when the user navigates to that section. Before the module request is returned from the server, validate the user's right to load that module and return an error code if they are not logged in or do not have the role required for that module.
Storing mxml serverside for dynamic view generation is not a tenable approach. Yes you can, no you should not. Non-trivial use of the site would bring down the server with a quickness unless you implement a good caching mechanism.
See Web-tier compilation of MXML files for more info though as it's an interesting concept.
Check out the Flex Chimp and this article that describes it.
Related
I'm building an asp.net web application that allows users to manage their person account(s) information. Users will have a single web user account, but in some cases it may be associated with multiple accounts at different store locations. So in order for a user to manage their account, I first need them to select the location they want to manage their account for.
This application is a class library that runs within a larger web site, it doesn't define the entire web site. I have a centralized method called GetCurrentStore() that will return the store if a selection exists in Session. If one is not selected, is Response.Redirect([Store Selection Page URL], true) the best way to handle getting one? I know this method throws an exception so it is a somewhat expensive mechanism, but I'm not sure I know of any alternatives that will prevent further processing of the response.
is Response.Redirect([Store Selection Page URL], true) the best way to handle getting one?
"Best" is somewhat subjective and very context-dependent, but some observations:
By accessing Session from your Class Library, you're increasing coupling (it needs to be called within the context of an HTTP Request, which, among other undesirable traits, makes it less testable). I'd get the name or id of the current store location in the UI tier, and pass it to the class library.
If you need to redirect the user to another page, the overhead of throwing an exception is probably negligible. But again, the class library is probably not the best place to do this: you should check if the current store location is in Session in the UI tier, and do the redirect there.
I'm creating a generic flexible site that I can use over and over again but with different features activated or deactivated. I'm looking for the best method to approach my solution.
Specific areas will need to be closed off in certain circumstances, for instance, the application will contain an event management page, but it will not always be required. The application will pull out the active and deactivated features from a data source.
They're going to be like Application wide settings, that will be required on each page, hiding away those settings that are turned off from the menu and not allowing users to access the deactivated feature pages.
I have thought of a number of ways to achieve this :
Store the feature statuses in the database, then on each time the page / menu is accessed / displayed, call the database requesting whether to hide the page / menu item.
Store the feature statuses in the database and access them on the application startup, store them application wide then they can be accessed as and when.
Put the feature statuses in the web config, this way we don't need to query the database every single time or have globally accessible properties.
I would like you advice on which method would be best, or if a better method is available I would be grateful. I don't want to hit the database too many times, or would a simple check like this not be too performance expensive? I'm also not sure if the web config is secure enough for managing active site features.
Regards,
I think putting configuration in configuration file(web.config) would be better option. Because while displaying page/loading menu going to database every time to see whether it should be de/active, required database trip which is overhead.
And if the configuration is stored in web.config it is easily accessible by admin and also easy to modify without compiling or changing anything.
So, in my view best option is to store configuration in web.config. In addition to that you can also make administration page which will change configuration settings and should be reflected in configuration file.
I suggest 2nd approach - store the settings in the database and then retrieve them at startup and store in application scoped containers.
The advantage of such approach over the web.config is that you can easily take client database and immediately run it in your development environment for testing/debugging. If, on the other hand, some settings are stored outside of the database, cloning the site means that you not only have to clone the database but also all the settings from various other resources (like the web.config).
The answer depends on how often you will be changing the status of the features.
If you are going to only set the statuses once when you clone the site and will never touch it again, go with option #2 (load on application start).
If there is any possibility that you will need to change the status of the features in the future, go with option #1 (get statuses on each page load). A simple datareader read to the db will not affect the speed of your site. The db is your friend, remember that's what it is there for. Also, if you ever need to change the statuses while the site is up and running, this method allows you to do so without restarting the entire application.
Whatever method you finally decide to implement, make sure the "application wide" location you store the settings is multi-threaded ready. Remember, each page request will be run on a separate thread and they will all access the same resource.
My suggestion taken from MS (multi-thread safe Singleton Pattern):
using System;
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
We have a flex application that connects to a proxy server which handles authentication. If the authentication has timeout out the proxy server returns a json formatted error string. What I would like to do is inspect every URLRequest response and check if there's an error message and display it in the flex client then redirect back to login screen.
So I'm wondering if its possible to create an event listener to all URLRequests in a global fashion. Without having to search through the project and add some method to each URLRequest. Any ideas if this is possible?
Unless you're only using one service, there is no way to set a global URLRequest handler. If I were you, I'd think more about architecting your application properly by using a delegate and always checking the result through a particular service which is used throughout the app.
J_A_X has some good suggestions, but I'd take it a bit farther. Let me make some assumptions based on the limited information you've provided.
The services are scattered all over your application means that they're actually embedded in multiple Views.
If your services can all be handled by the same handler, you notionally have one service, copied many times.
Despite what you see in the Adobe examples showing their new Service generation code, it's incredibly bad practice to call services directly from Views, in part because of the very problem you are seeing--you can wind up with lots of copies of the same service code littered all over your application.
Depending on how tightly interwoven your application is (believe me, I've inherited some pretty nasty stuff, so I know this might be easier said than done), you may find that the easiest thing is to remove all of those various services and replace them by having all your Views dispatch a bubbling event that gets caught at the top level. At the top level, you respond to that event by calling one instance of your service, which is again handled in one place.
You may or may not choose to wrap that single service in a delegate, but once you have your application archtected in a way where the service is decoupled from your Views, you can make that choice at any time.
Would you be able to extend the class and add an event listener in the object's constructor? I don't like this approach but it could work.
You would just have to search/replace the whole project.
I am using The Policy Injection Application Block to log methods that are called in my ASP.NET application. I would like these log entries to include information like the current user identity, whether the user is authenticated and so forth. All of this information is provided by the ManagedSecurityContextInformationProvider, but I can't figure out how to get the PIAB to use that provider and how to get that information into my log file.
I may be missing something obvious, but I can't quite figure out what it is.
Sorry to say, it looks like there is no way to get the ManagedSecurityContextInformationProvider information into method call logs. That information is usually logged in extended properties but the LogCallHandler.GetLogEntry method dumps out all of the method parameters and assigns them to the TraceLogEntry ExtendedProperties.
It seems to me that you could either modify the block to add that information or (even better) create your own Custom Call Handler based on LogCallHandler that adds the information that you require. Either option is not that much work.
I am trying to build an ASP.NET 3.5 website that allows users to log in and browse a couple of pages. I would like to restrict certain users to be able to view certain pages but I'm having trouble coming up with a custom and flexible system. I have seen MS's version of this but it's not what I am looking for. Can anyone direct me to some good online articles or even a video tutorial so I can do further research. Thanks!
P.S. I have tried creating a class that inherits from System.Web.UI.Page which does some checking but it's getting messy. All my other pages inherit from that common page. Is this a common practice? How have you guys solved this problem in the past?
The best way to implement this would be, Forms Authentication coupled with Custom Role Provider.
Hope you know, for Forms Authentication to work, you need not have to use the Complete Database Setup that MS uses to Authenticate.
You can simply have your own Database and Validate a user yourself, and just set the cookie.
String UserName = "CoolGuy";
Boolean isValidUser = YourClass.YourMethod(UserName);
if (isValidUser)
{ FormsAuthentication.setAuthCookie(UserName, false); }
This will authenticate the user "CoolGuy" for the session, provided YourMethod returns true.
You can use this, coupled with custom role provider. This gives you the facility to check User.IsInRole("Role"); in your code.
To Start with CustomRoleProvider.. here is a good reference... http://davidhayden.com/blog/dave/archive/2007/10/17/CreateCustomRoleProviderASPNETRolePermissionsSecurity.aspx
Raja
Well, without knowing the exact details of your app, one thing you could use is the Role Manager built into the Membership API.
Basically, you would create roles for each page and assign users to the roles (pages) you would want them to view.
In the code behind for each page, on the On_Load event, I would simply call the method
if(Roles.IsUserInRole(rolePageName))
{
//Continue page loading logic
}
{
//Redirect or transfer the user elsewhere
}
For this kind of logic you may want to reconsider using an inherited page, otherwise you're going to have to come up with a way to retrieve the URL of the page and pass that into some long list of if-else or switch statements to call the proper Roles.IsUserInRole method.