Session time out error - session

My application is expiring before 20 minutes and even when we are working on it also it is expiring may I know what I have to change?..
public class CheckSessionOutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
if (ctx.Session != null)
{
if (ctx.Session.IsNewSession)
{
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
if (ctx.Request.IsAuthenticated)
{
FormsAuthentication.SignOut();
HttpContext.Current.Session.Clear();
RedirectResult redirectingto = new RedirectResult("~/Account/Timeout");
filterContext.Result = redirectingto;
}
else
{
string loginUrl = FormsAuthentication.LoginUrl;
RedirectResult redirectto = new RedirectResult(loginUrl);
filterContext.Result = redirectto;
}
}
}
}
base.OnActionExecuting(filterContext);
}
Web.config file
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1000"/>
</authentication>
<sessionState mode="InProc" timeout="20" />

Related

Can't find user tables MVC Web API

After successful registration, can't find aspnet user tables and also when I tried to login, it returns invalid grant type
public IdentityResult Register(string username, string password)
{
var userStore = new UserStore<IdentityUser>();
var manager = new UserManager<IdentityUser>(userStore);
var user = new IdentityUser() { UserName = username, Email = username };
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 3
};
IdentityResult result = manager.Create(user, password);
return result;
}
when I tried to login, it returns invalid grant type
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userStore = new UserStore<IdentityUser>(new ApplicationDbContext());
var manager = new UserManager<IdentityUser>(userStore);
var user = await manager.FindAsync(context.UserName, context.Password);
if(user !=null)
{
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("Username", user.UserName));
identity.AddClaim(new Claim("Email", user.Email));
identity.AddClaim(new Claim("LoggedOn", DateTime.Now.ToString()));
context.Validated();
}
else
{
return;
}
}
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext()
: base("MyEntities")
{
}
public DbSet<userlogindetails> userlogindetails{ get; set; }
}
webconfig
<add name="MyEntities" connectionString="metadata=res://*/Models.MyModel.csdl|res://*/Models.MyModel.ssdl|res://*/Models.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=MY-PC\SQLEXPRESS;initial catalog=MyDB;user id=user;password=pass;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
It turns out that i need to add Default ConnectionString
<add name="DefaultConnection" connectionString="Data Source=My-PC\SQLEXPRESS;Initial Catalog=MyDB;User ID=username;Password=pass" providerName="System.Data.SqlClient" />

Action Filter to check Session MVC3

I want to create some custom Filters in my application
After successful login i keep logged in user details in a session and want to check the session is expired or not ( If session expired i want to redirect to login page) and i need a filter for this.
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
SchoolApp.ViewModels.CurrentSessionModel model=(SchoolApp.ViewModels.CurrentSessionModel)HttpContext.Current.Session["mySession"];
if (model == null)
{
//Redirect to Login page
}
else
{
base.OnActionExecuting(filterContext);
}
}
}
But the problem is this will fire for every rquests even while loading Login page . So how can i make a useful filter control that check for session
Looks like you're trying to do wrong things there. Check your web.config file - it should have section like:
<authentication mode="Forms">
<forms loginUrl="http://www.your_domain.com/login" name="cookie_name" defaultUrl="default_url" domain="your_domain" enableCrossAppRedirects="true" protection="All" slidingExpiration="true" cookieless="UseCookies" timeout="1440" path="/" />
</authentication>
If your session is expired (cookie with cookie_name non exists anymore) - user will be automatically redirected to loginUrl
If you still want to use filters - there's solution that allows you to exclude global filter for some controllers/actions:
assuming you have method in global.asax.cs:
private static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
IFilterProvider[] providers = FilterProviders.Providers.ToArray();
FilterProviders.Providers.Clear();
FilterProviders.Providers.Add(new ExcludeFilterProvider(providers));
filters.Add(DependencyResolver.Current.GetService<MyFilter>(), 2); // add your global filters here
}
Call it in your global.asax.cs:
RegisterGlobalFilters(GlobalFilters.Filters);
Filter provider class will look like:
public class ExcludeFilterProvider : IFilterProvider
{
private readonly FilterProviderCollection _filterProviders;
public ExcludeFilterProvider(IFilterProvider[] filters)
{
_filterProviders = new FilterProviderCollection(filters);
}
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
Filter[] filters = _filterProviders.GetFilters(controllerContext, actionDescriptor).ToArray();
if (filters.Select(f => f.Instance).OfType<OverrideExcludeFilter>().Any())
return filters;
IEnumerable<ExcludeFilterAttribute> excludeFilters = (from f in filters where f.Instance is ExcludeFilterAttribute select f.Instance as ExcludeFilterAttribute);
var excludeFilterAttributes = excludeFilters as ExcludeFilterAttribute[] ?? excludeFilters.ToArray();
if (excludeFilterAttributes.FirstOrDefault(f => f.AllFilters) != null)
{
return new Collection<Filter>();
}
var filterTypesToRemove = excludeFilterAttributes.SelectMany(excludeFilter => excludeFilter.FilterTypes);
IEnumerable<Filter> res = (from filter in filters where !filterTypesToRemove.Contains(filter.Instance.GetType()) select filter);
return res;
}
}
ExcludeFilter attribute class:
public class ExcludeFilterAttribute : FilterAttribute
{
private readonly Type[] _filterType;
public ExcludeFilterAttribute(bool allFilters)
{
AllFilters = allFilters;
}
public ExcludeFilterAttribute(params Type[] filterType)
{
_filterType = filterType;
}
/// <summary>
/// exclude all filters
/// </summary>
public bool AllFilters { get; private set; }
public Type[] FilterTypes
{
get
{
return _filterType;
}
}
}
And usage sample:
[ExcludeFilter(new[] { typeof(MyFilter) })]
public ActionResult MyAction()
{
//some codes
}
So this way your filter of type MyFilter won't fire for specified action

How to modify Authorize attribute to allow a group of User Roles in MVC 3

In my MVC3 wep app, I have extended the Authorize attribute like below
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (Authenticate.IsAuthenticated() && httpContext.User.Identity.IsAuthenticated)
{
var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
var roles = ticket.UserData.Split('|');
var identity = new GenericIdentity(ticket.Name);
httpContext.User = new GenericPrincipal(identity, roles);
}
}
return base.AuthorizeCore(httpContext);
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!Authenticate.IsAuthenticated())
HandleUnauthorizedRequest(filterContext);
base.OnAuthorization(filterContext);
}
In my Actions, I use it like
[MyAuthorize(Roles = "Member,Inspector,SalesRep,Admin,SuperAdmin")]
public ActionResult OrderUpload()
Now, I have to specify each user role in every action. What I would like to do is
specify something like below
[MyAuthorize(Roles = "Member")]
public ActionResult OrderUpload()
and this should allow any User Role that are equal or above "Member". So a "SalesRep" should be allowed, where as "Visitor", who is below the "Member" should not be allowed.
All User Roles are enum with increasing numbers
public enum UserAccountType
{
Visitor = 5,
Member = 10,
Inspector = 15,
SalesRep = 20,
Admin = 25,
SuperAdmin = 30
}
How do I modify MyAuthorizeAttribute to make this work?
Thanks
Here is my working code
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (Authenticate.IsAuthenticated() && httpContext.User.Identity.IsAuthenticated)
{
var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
string[] roles = null;
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
roles = ticket.UserData.Split('|');
var identity = new GenericIdentity(ticket.Name);
httpContext.User = new GenericPrincipal(identity, roles);
}
if (Roles == string.Empty)
return true;
//Assuming Roles given in the MyAuthorize attribute will only have 1 UserAccountType - if more than one, no errors thrown but will always return false
else if ((UserAccountType)Enum.Parse(typeof(UserAccountType), roles[0]) >= (UserAccountType)Enum.Parse(typeof(UserAccountType), Roles))
return true;
else
return false;
}
else
return false;
//return base.AuthorizeCore(httpContext);
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!Authenticate.IsAuthenticated())
HandleUnauthorizedRequest(filterContext);
base.OnAuthorization(filterContext);
}
}
I don't use AuthorizeAttribute but ActionFilter (it's just me and that's how I learned it) but What I would do is add a property on the AuthorizeAttribute that gets updated when the Attribute gets triggered before the Action.
public class MyAuthorizeAttribute : AuthorizeAttribute
{
private string Role = "";
public MyAuthorizeAttribute(string role){
this.Role = role;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
:
:
:
// now do a check if the Role is authorized or not using your enum.
// return error page if not
if(RoleisAuthorized)
return;
else
// error page
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
:
:
:
}
}
Now after you got the Role, go get it from the enum and compare if the role is allowed to access the page or not, if not return an error page. So since I'm not familiar with OnAuthorization, I would place the process inside AuthorizeCore.

MVC3 + Elmah = defaultredirect in web.config doesn't work

I'm trying to link MVC3 with Elmah. Everything works great and all errors are handled and logged but i have problem with frontend for users with custom errors. I wrote global filter
public class ElmahHandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(ExceptionContext context)
{
base.OnException(context);
var e = context.Exception;
if (!context.ExceptionHandled // if unhandled, will be logged anyhow
|| RaiseErrorSignal(e) // prefer signaling, if possible
|| IsFiltered(context)) // filtered?
return;
LogException(e);
}
private static bool RaiseErrorSignal(Exception e)
{
var context = HttpContext.Current;
if (context == null)
return false;
var signal = ErrorSignal.FromContext(context);
if (signal == null)
return false;
signal.Raise(e, context);
return true;
}
private static bool IsFiltered(ExceptionContext context)
{
var config = context.HttpContext.GetSection("elmah/errorFilter")
as ErrorFilterConfiguration;
if (config == null)
return false;
var testContext = new ErrorFilterModule.AssertionHelperContext(
context.Exception, HttpContext.Current);
return config.Assertion.Test(testContext);
}
private static void LogException(Exception e)
{
var context = HttpContext.Current;
ErrorLog.GetDefault(context).Log(new Error(e, context));
}
}
and I registered filter in Global.asax
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandleErrorAttribute());
//filters.Add(new HandleErrorAttribute());
}
but when exception is raised, handler handled it but doesnt use defaultredirect path from web.config. It looking view in ~/Shared/Error.cshtml
My in webconfig
<customErrors mode="On" defaultRedirect="~/Home/NeutralError">
<error statusCode="404" redirect="~/Home/NeutralErrorNotFound" />
</customErrors>
Any ideas? : |
The HandleError attribute as default looks for the Error view in the shared folder and not works based upon the defaultRedirect properties set up on customErrors section. You can tell the HandleError to look for a different view name but I think in your case you want to redirect to some other action. I hope this will work (not tested),
public override void OnException(ExceptionContext context)
{
base.OnException(context);
var e = context.Exception;
if (!context.ExceptionHandled // if unhandled, will be logged anyhow
|| RaiseErrorSignal(e) // prefer signaling, if possible
|| IsFiltered(context)) // filtered?
return;
LogException(e);
// newly added
if (context.Exception is HttpException)
{
if(((HttpException)context.Exception).GetHttpCode() == 404)
context.Result = new RedirectResult("~/Home/NeutralErrorNotFound");
}
context.Result = new RedirectResult("~/Home/NeutralError");
}
Setting the View of your base class in your OnException method seemed to fix this for me.
public override void OnException(ExceptionContext context)
{
base.View = "~/views/error/errorindex.cshtml"; // New code here...
base.OnException(context);
var e = context.Exception;
if (!context.ExceptionHandled // if unhandled, will be logged anyhow
|| RaiseErrorSignal(e) // prefer signaling, if possible
|| IsFiltered(context)) // filtered?
return;
LogException(e);
}

How to create custom JsonAuthorize Attribute to secure actions which returns JsonResults?

I was thinking how to correctly secure JsonResult action with custom attribute instead of doing kind of this on each action like saying here ASP.NET MVC JsonResult and AuthorizeAttribute
if (!User.Identity.IsAuthenticated)
return Json("Need to login");
But the question is how could i create such attribute which would return Json.
So i've started from that:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class JsonAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
//?
}
//Need to return json somehow ?
}
}
Bot how i may return json result from such attribute? any ideas?
You can use an ActionFilterAttribute which allows you to return a result without using the httpcontext.response.write or anything.
public class JsonActionFilterAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!HttpContext.Current.User.Identity.IsAuthenticated) {
filterContext.Result = new JsonResult() { Data = "Need to login." };
}
base.OnActionExecuting(filterContext);
}
}
1 way is to override AuthorizeAttribute.HandleUnauthorizedRequest
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
throw new CustomUnauthorizedException();
}
... And then in your Global.asax:
protected void Application_Error(object sender, EventArgs e)
{
Exception error = Server.GetLastError();
if (error is CustomUnauthorizedException) {
if (AjaxRequest(Request)) {
... return Json response.
} else {
... redirect
}
}
}
So you can throw the exception anywhere in your codebase and you've centralized the handling of that exception in Global.asax
Try this.. it works for me
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
dynamic ResponseObj = new JObject();
ResponseObj.Message = "Authorization has been denied for this request.";
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(ResponseObj);
actionContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.Unauthorized,
Content = new StringContent(jsonString, System.Text.Encoding.UTF8,"application/json")
};
}

Resources