Handling PrincipalPermission exceptions in MVC3 - asp.net-mvc-3

On my MVC application I decorated some of the methods of my controller with this:
[PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
public ActionResult Create(FormCollection collection)
{
try {
...
}
catch {
return View();
}
}
And indeed if I am not logged in or not with the correct role an exception is thrown by the MVC application. The problem is I am not getting the application redirected to an error page.
I tried creating a base controller like this:
[HandleError]
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
// Make use of the exception later
this.Session["ErrorException"] = filterContext.Exception;
// Mark exception as handled
filterContext.ExceptionHandled = true;
// ... logging, etc
// Redirect
filterContext.Result = this.RedirectToAction("Error", "Home");
base.OnException(filterContext);
}
}
And then adding the Error view in the Home controller as well as the actual View. The problem is that when I try this in Visual Studio I first get an exception upon entering the protected action method:
SecurityException was unhandled by the application
and then I have to do Debug|Continue and only then I am redirected to the the Error view but that is unacceptable in a production application because it should go straight to the Error view.

Just wondering why you are not just using standard AuthorizeAttribute. Pretty sure it would do that same thing and just work?
E.g.
[Authorize(Roles="Administrator")]
public ActionResult Create(FormCollection collection)
Article on general MVC security here.
http://www.codeproject.com/Articles/288631/Secure-ASP-NET-MVC3-applications

Related

Page is not redirecting to login page after session expire using AJAX

In my MVC project most of the calls to server are done using Ajax. It works smoothly until the session expires. I have added custom attribute to redirect the page to login page once the session gets expired. But when the call is from AJAX then it is not redirecting to login page.
I have gone through many threads regarding this which has basically suggested to use OnActionExecuted method of ActionFilterAttribute class, but while doing so i am only getting the type HttpActionExecutedContext instead of type ActionExecutingContext.
Here's my code:
public class SessionExpired : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
//My Code to handle the session event
base.OnActionExecuted(actionExecutedContext);
}
}
Thanks in advance.
Ajax functions are used to get data or to post data primarily. If you are trying to redirect to any page using ajax request mechanism then you are going in wrong direction.
Create a custom Action Filter that handles session expiration and if session is null, redirect to Login Action.
namespace Mayur.Web.Attributes
{
public class SessionTimeoutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
if (HttpContext.Current.Session["ID"] == null)
{
filterContext.Result = new RedirectResult("~/Home/Login");
return;
}
base.OnActionExecuting(filterContext);
}
}
}

Simple Injector and routeattribute webapi

I have a WebApi 2 Application and I'm using simple injector and all is working ok.
But today I tried to use the [RoutePrefix] and [Route] attributes to resolve my routes on a particular controller and it seems that simple injector is not able to create an instance of my controller.
i'm getting this error
An error occurred when trying to create a controller of type
'NewController'. Make sure that the controller has a parameterless
public constructor. Type
'Public.API.Controllers.NewController' does not have a default
constructor
Stack trace:
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
my controller looks like this
[Authorize]
[RoutePrefix("api/New")]
public class NewController : ApiController
{
private IUserService userService;
public NewController(IUserService userService)
{
this.userService = userService;
}
[HttpPost]
[AllowAnonymous]
public async Task<IHttpActionResult> Register(ApiRegisterUserRequestModel model) {
return Content(HttpStatusCode.OK, "reponse");
}
[HttpPost]
[AllowAnonymous]
[Route("ForgotPasswordSendEmail")]
public async Task<IHttpActionResult> ForgotPasswordSendEmail(
[FromBody] ApiForgotPasswordRequestModel model)
{
var response = "cool";
return Content(HttpStatusCode.OK, response);
}
}
If I make a request to the Register action I get a response, but if I make a request to the ForgotPasswordSendEmail action then I get the error I mentioned above.
The simple injector configuration I have is the Basic setup mentioned here
https://simpleinjector.readthedocs.org/en/latest/webapiintegration.html
UPDATE
I'm using OWIN and JWT token authentication, and I have a global.asax and a startup file in my project and both were configured to use webapi.
These were my Startup class and Application_Start
//startup class
public class Startup
{
public void Configuration(IAppBuilder app)
{
SimpleInjectorWebApiInitializer.Initialize();
HttpConfiguration httpConfig = new HttpConfiguration();
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
WebApiConfig.Register(httpConfig);
app.UseWebApi(httpConfig);
}
}
//Application_Start
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
SimpleInjector.Configure();
SimpleInjectorWebApiInitializer.Initialize();
}
I removed all of the api configuration from the startup and left if like this
public class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
}
}
and it started to work.
now, why wasn't it working using the [Route] attribute and without it all was fine? it's a mystery to me.
I've been trying to reproduce this issue, but with no success. You typically get the "Make sure that the controller has a parameterless public constructor" error in case the registered IDependencyResolver.GetService returns null and the requested type does not have a default constructor.
If you, as you said, follow Simple Injector's configuration guidance, the SimpleInjectorWebApiDependencyResolver will not return null, but will either return a valid controller instance -or- will throw an expressive exception. The default guidance states that you at least do the following:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
If you use this code, it's very unlikely that you get this "Make sure that the controller has a parameterless public constructor" error. Especially in the situation where the controller can be resolved when called using one action, while it fails to initialize during another.
So please check the following:
You are using the code as shown above.
Are you sure that api/New/Register call actually goes through the NewController. You can set a break point in its constructor and the Register method.
The NewController can actually be resolved correctly when manually calling container.GetInstance<NewController>().

How to create a servlet on the fly

For below URL's I receive a 404 error, this is fine since the URL's do not exist. Is it possible to create these servlets while the server is running before the error page is returned ?
http://127.0.0.1:8888/test1
http://127.0.0.1:8888/test1/test2
I'm thinking perhaps to create a generic controller that intercepts all urls if the current servlet does not exist, then create it ?
Assuming that by Spring you mean Spring MVC, you could do something like this:
#Controller
public class YourController {
#RequestMapping("/mappingA")
public void methodA() {
// (...)
}
#RequestMapping("/mappingB")
public void methodB() {
// (...)
}
// Catches all non-matched requests.
#RequestMapping("/*")
public void fake404(HttpServletRequest request) {
var uri = request.getRequestURI();
// (...)
}
}

#ExceptionHandler in Spring

In my application I have configured an error page in web.xml. I need to override that for a specific controller based on a condition. Here when a condition becomes true I need to redirect to a specific error page otherwise normal error page should be rendered.
Here is the code. Please help me.
#Controller
public class Test{
#ExceptionHandler(Exception.class)
public ModelAndView generateException(HttpServletRequest httpServletRequest){
if(condition) {
return new ModelAndView("myError.jsp");
} else {
//should execute default error page.
}
}
}
Throw the exception again which will be handled by DefaultHandlerExceptionResolver to respond with the error page defined in your web.xml; It doesn't invoke the same Exception Handler of the controller.
#ExceptionHandler(Exception.class)
public ModelAndView generateException(Exception ex) throws Exception{
if(condition) {
return new ModelAndView("myError.jsp");
} else {
//should execute default error page.
throw ex;
}
}

Spring 3.0 RESTful Controller Fails on Redirect

I am setting up a simple RESTful controller for a Todo resource with an XML representation. It all works great - until I try to redirect. For example, when I POST a new Todo and attempt to redirect to its new URL (for example /todos/5, I get the following error:
Error 500 Unable to locate object to be marshalled in model: {}
I do know the POST worked because I can manually go to the new URL (/todos/5) and see the newly created resource. Its only when trying to redirect that I get the failure. I know in my example I could just return the newly created Todo object, but I have other cases where a redirect makes sense. The error looks like a marshaling problem, but like I said, it only rears itself when I add redirects to my RESTful methods, and does not occur if manually hitting the URL I am redirecting to.
A snippet of the code:
#Controller
#RequestMapping("/todos")
public class TodoController {
#RequestMapping(value="/{id}", method=GET)
public Todo getTodo(#PathVariable long id) {
return todoRepository.findById(id);
}
#RequestMapping(method=POST)
public String newTodo(#RequestBody Todo todo) {
todoRepository.save(todo); // generates and sets the ID on the todo object
return "redirect:/todos/" + todo.getId();
}
... more methods ...
public void setTodoRepository(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
private TodoRepository todoRepository;
}
Can you spot what I am missing? I am suspecting it may have something to do with returning a redirect string - perhaps instead of it triggering a redirect it is actually being passed to the XML marshaling view used by my view resolver (not shown - but typical of all the online examples), and JAXB (the configured OXM tool) doesn't know what to do with it. Just a guess...
Thanks in advance.
This happend because redirect: prefix is handled by InternalResourceViewResolver (actually, by UrlBasedViewResolver). So, if you don't have InternalResourceViewResolver or your request doesn't get into it during view resolution process, redirect is not handled.
To solve it, you can either return a RedirectView from your controller method, or add a custom view resolver for handling redirects:
public class RedirectViewResolver implements ViewResolver, Ordered {
private int order = Integer.MIN_VALUE;
public View resolveViewName(String viewName, Locale arg1) throws Exception {
if (viewName.startsWith(UrlBasedViewResolver.REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(UrlBasedViewResolver.REDIRECT_URL_PREFIX.length());
return new RedirectView(redirectUrl, true);
}
return null;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}

Resources