Your solution is similar to mine except that I did this.
Up vote 0 down vote favorite share g+ share fb share tw.
I have an application where some users belong to a Role, but may not actually have access to certain data within a URL. For instance the following url is open to all users /Library/GetFile/1 However, some users may not have access to file1, but I can't use the Authorize attribute to detect that. I want instead to redirect those users to an unauthorized or accessdenied page.
I'm using Forms Authentication and my config is set up like this my custom errors block is like this I am attempting to return the HttpUnauthorizedResult if the user does not have access, but I just get redirected to the login page, which isn't valid here because the User is Authenticated already. It appears that the HttpUnauthorizedResult is setting the HTTP Response Code to 401 which Forms Authentication is hijacking and sending the user to the Login page. Throwing the UnauthorizedAccessException doesn't seem to work either always redirecting the user to an IIS Error page even though I've updated my RegisterGlobalFilters to filters.
Add(new HandleErrorAttribute { ExceptionType = typeof(UnauthorizedAccessException), View = "Unauthorized", Order = 3 }); If I change UnauthorizedAccessException to a custom Exception the redirect works and for now that's what I've done. Asp. Net-mvc-3 iis7 forms-authentication unauthorized link|improve this question edited Dec 2 '11 at 14:51 asked Dec 1 '11 at 21:54Steven457 57% accept rate.
Your solution is similar to mine except that I did this: Create a custom exception, UnauthorizedDataAccessException. Create a custom exception filter (so that it could log the invalid access attempt). Register my custom exception attribute as a global filter in App_start.
Create a marker interface, ISecureOwner and added it to my entity. Add a secure 'Load' extension method to my repository, which throws the exception if the current user is not the owner of the entity that was loaded. For this to work, entity has to implement ISecureOwner that returns the id of the user that saved the entity.
Note that this just shows a pattern: the details of how you implement GetSecureUser and what you use to retrieve data will vary. However, although this pattern is okay for a small app, it is a bit of hack, since that kind of security should be implemented deep down at the data level, using ownership groups in the database, which is another question :) public class UnauthorizedDataAccessException : Exception { // constructors } public class UnauthorizedDataAccessAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (filterContext.Exception.GetType() == Typeof(UnauthorizedDataAccessException)) { // log error filterContext. ExceptionHandled = true; filterContext.
Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "UnauthorizedDataAccess" })); } else { base. OnException(filterContext); } } // marker interface for entity and extension method public interface ISecureOwner { Guid OwnerId { get; } } // extension method public static T SecureFindOne(this IRepository repository, Guid id) where T : class, ISecureOwner, new() { var user = GetSecureUser(); T entity = repository. FindOne(id); if (entity.
OwnerId! = user. GuidDatabaseId) { throw new UnauthorizedDataAccessException(string.
Format("User id '{0}' attempted to access entity type {1}, id {2} but was not the owner. The real owner id is {3}. ", user.
GuidDatabaseId, typeof(T). Name, id, entity. OwnerId)); } return entity; } // Register in global.
Asax public static void RegisterGlobalFilters(GlobalFilterCollection filters) { var filter = new UnauthorizedDataAccessAttribute { ExceptionType = typeof(UnauthorizedDataAccessException) }; filters. Add(filter); filters. Add(new HandleErrorAttribute()); } // Usage: var ownedThing = myRepository.
SecureFindOne(id)).
In the end this is what I did except for 2 things. I didn't create a Custom HandleErrorAttribute just set the ExceptionType and Order on a second HandleError filter in my RegisterGlobalFilters method. I LIKE the idea of your 'Secure' extension on your repository!
I may play with that idea some more. – Steven Dec 4 '11 at 15:05 @Steven, I was going to dispense with an attribute and just register the standard HandleError filter, but I noticed that you could only specify a View. Since I am using Areas, I need to be explicit about my controller.
– Rob Kent Dec 5 '11 at 8:38.
You can restrict access to certain roles. If an unauthorized role tries to access a resource you can redirect them to a specific url. Look at this other SO question: attribute-for-net-mvc-controller-action-method, there are good answers there.
You can check in your code if a user belongs to a role: User. IsInRole("RoleToTest"); you can also apply attributes to your controllers/action methods. Anyhow it is all explained in the link I specified above.
* EDIT * You could override OnException in your base Controller. Implement a custom exception, e.g. , AccessNotAuthorizedAccessException. In OnExcepton, if you detect your custom exception, just redirect to a friendly url that shows the 'Not authorized...' message.
I understand how to check Roles AND use the Authorize attribute. The problem is that the user doesn't have access to the specific entity. I don't want to Redirect them to a View, I want to be able to throw an error or return the HttpUnauthorizedResult and have MVC handle it.
– Steven Dec 2 '11 at 14:43 If you do not wish to redirect them to a view that says something like 'You are not authorized to view this content', what is it that you are expecting? I will post an updated answer which will give you a possible solution using a custom Authorize Attribute – santiagoIT Dec 2 '11 at 16:50.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.