How to clear session on Custom HandleError Attribute in MVC? - c#

I am creating my own custom HandleError attribute on MVC.
public class MVCError : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
//Supposed to remove session here
}
}
But it seems that I cannot use the Session to remove specific session on my website. Is this possible? Or do I need to clear my session on Global.asax file:
protected void Application_Error()
{
Session.Remove("Check");
Debug.WriteLine("An error has occurred.");
}

You can clear use HttpContext.Current object HttpContext.Current.Session.Remove("Check");
public class MVCError : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
//Supposed to remove session here
HttpContext.Current.Session.Remove("Check");
}
}

Related

OnActionExecuting Not Getting Executed

I am troubleshooting a ASP.NET MVC application and on one server the OnActionExecuting is not firing. It has been a long time since I looked at filters. What can keep the OnActionExecuting from running? The effect in our application is the user context never really gets set up (Initialize)... so everything redirects the user back to the login page.
Here is the code of the filter. Note "Jupiter" was the codename of the project
public class JupiterAuthenticationFilter : IActionFilter
{
private readonly IJupiterContext _jupiterContext;
public JupiterAuthenticationFilter(IJupiterContext jupiterContext)
{
if (jupiterContext == null)
{
throw new ArgumentNullException("jupiterContext");
}
_jupiterContext = jupiterContext;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
_jupiterContext.Initialize();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
It can happen when your Controller has System.Web.MVC implementation, but ActionFilter has System.Web.Http.

Throw HttpException in CustomAuthorizeAttribute

As described in the linked posts, I am not satisfied with the built in AuthorizeAttribute, because it always redirects to the declared login-page. I need different behaviour between 401-NotAuthenticated (I know it is called Unauthorized) and 403-Forbidden. Forbidden shouldn't link to the login-page.
As in this or this solutions suggested, I implemented a custom attribute called AuthenticateAndAuthorizeAttribute inheriting from AuthorizeAttribute.
public class AuthenticateAndAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute {
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext) {
if (filterContext.HttpContext.Request.IsAuthenticated) {
filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
}
else {
base.HandleUnauthorizedRequest(filterContext);
}
}
}
All in all it does what it is supposed to do. But, because only the HttpStatusCode of the response is changed, I get an empty page. I know it is because there is no custom error page defined in the web.config. Instead we use the solution with "overriding" the method protected void Application_Error(object sender, EventArgs e) in the global.asax. This enables us, to create different error pages for default requests and ajax requests.
Unfortunatly this does not work when just setting the status code of the response. So I implemented the attribute, with throw HttpExceptions.
public class AuthenticateAndAuthorizeAttribute : AuthorizeAttribute {
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
if (filterContext.HttpContext.Request.IsAuthenticated) {
throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, Forbidden!");
} else {
throw new HttpException((int)System.Net.HttpStatusCode.Unauthorized, "Not Authenticated!");
}
}
}
Now I wonder, if this is a common/correct way to deal with authentication and authorization or if I break some built-in (security)features of asp.net? Could someone see any problems with this solution?

Custom authorization attribute not working in WebAPI

public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return true;// if my current user is authorised
}
}
Above is my CustomAuthorizeAttribute Class
and
[CustomAuthorize] // both [CustomAuthorize] and [CustomAuthorizeAttribute ] I tried
public class ProfileController : ApiController
{
//My Code..
}
When I'm calling
http://localhost:1142/api/Profile
It is not firing CustomAuthorizeAttribute
More over My FilterConfig class is look like below
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizeAttribute());
}
}
Please help if I miss something.
Looks like you are using an MVC filter instead of a Web API filter. It can be detected in the sample because it uses HttpContextBase. Instead use the filter from the System.Web.Http.Filters namespace.
You need to override OnAuthorization or OnAuthorizationAsync on the Web API filter.
You don't need to register a global filter and decorate your controller with it. Registering it will make it run for all controllers.
Web API filter code:
https://github.com/aspnetwebstack/aspnetwebstack/blob/master/src/System.Web.Http/Filters/AuthorizationFilterAttribute.cs
YOur custom attribute should inherit from System.Web.Http.Filters.AuthorizationFilterAttribute
and it should look like this
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class CustomAuthorizeAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
public override bool AllowMultiple
{
get { return false; }
}
public override void OnAuthorization(HttpActionContext actionContext)
{
//Perform your logic here
base.OnAuthorization(actionContext);
}
}
Try with this.
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
return true;
}
}
To add onto the other answers that have you inherit from System.Web.Http.Filters.AuthorizationFilterAttribute, I put this into my OnAuthorization method to make sure the user was logged in:
if (!actionContext.RequestContext.Principal.Identity.IsAuthenticated)
{
// or whatever sort you want to do to end the execution of the request
throw new HttpException(403, "Forbidden");
}

How to call controller method in global.asax?

I want to call controller method in Global.asax. Code is given below.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//here we can subscribe user to a role via Roles.AddUserToRole()
}
}
This event is in global.asax. I want to call controller method which return user permissions from database. How this is possible to call controller method here after that I will save user permissions in session and my controller constructor? Code is given below.
public class AccountController : Controller
{
private readonly ISecurityService securityService;
public AccountController(ISecurityService securityService)
{
this.securityService = securityService;
}
}
Please guide me.
You could handle this using a custom AuthorizeAttribute. This allows you to place an attribute on the top of any controllers / methods which you require authentication to be successful in order to call. This lets you override AuthorizeCore which you can then use to do any custom authorization you want to perform. You can also save any other information to session from this method.
For example:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// do your own athorization stuff here
}
}
Then you can decorate you controllers that require the use of this authorization either with your attribute:
[CustomAuthorize]
public class AccountController : Controller
{
}
Or using a base controller:
[CustomAuthorize]
public class BaseAuthController : Controller
{
}
public class AccountController : BaseAuthController
{
}
i Resolve this issue by my self i call service method in global.asax by resolving dependency issue below is the solution of the above problem.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
IUnityContainer container = GetUnityContainer();
ISecurityService securityService = container.Resolve<SecurityService>();
var list = securityService.GetUserRolesandPermissions("1");
}
}
Thank you every one.

Creating an Attribute to check for Exceptions

I'm creating an attribute so that whenever an exception occurs on my site, I'll receive an email detailing the exception. I've got so far but my Attribute code doesn't seem to fire if an exception occurs:
public class ReportingAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
// This will generate an email to me
ErrorReporting.GenerateEmail(filterContext.Exception);
}
}
Then above my Controller I'm doing:
[ReportingAttribute]
public class AccountController : Controller
The other way to do it is ofcourse putting ErrorReporting.GenerateEmail(ex) inside my catch blocks? There must be a simpler way? Thats why I thought of creating the Attribute to handle this
For the purpose of logging all uncaught exceptions, you can define the following method in your Global.asax.cs file:
private void Application_Error(object sender, EventArgs e)
{
try
{
//
// Try to be as "defensive" as possible, to ensure gathering of max. amount of info.
//
HttpApplication app = (HttpApplication) sender;
if(null != app.Context)
{
HttpContext context = app.Context;
if(null != context.AllErrors)
{
foreach(Exception ex in context.AllErrors)
{
// Log the **ex** or send it via mail.
}
}
context.ClearError();
context.Server.Transfer("~/YourErrorPage");
}
}
catch
{
HttpContext.Current.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
Attribute just by itself can not define a behaviour, but its used for make some marks over your code data. You should write a code, where you
get an exception
check for given attribute presence in the method that raised an exception
if it is present, collect and send the data you need.
Why not create an base controller:
public ApplicationBaseController : Controller
{
public override void OnException(ExceptionContext context)
{
//Send your e-mail
}
}
And derive your controller from ApplicationBaseController
public HomeController : ApplicationBaseController
{
//.....
}

Categories