locked
page load event RRS feed

  • Question

  • User-194957375 posted

    Hello! Sorry for my english!  ))) I need an event preceding the loading of the MAIN page, so that after some verification, switch the user to the "Access denied" page, if necessary.

    I check for example in Application_BeginRequest,

    but not only the event of the main page arrives there, but also all sorts of PartialResult'y, and other requests.

    How to distinguish a request in begin_request from a page (for example, localhost: port \ Home \ List) from all ajax calls,signalR calls, and I did not find partial pages.
    I rummaged around in the debugger for a long time, but did not understand.

    second way - This is to write an authentication class

    public class AuthorizeClass1 : FilterAttribute, IAuthenticationFilter
    {    public void OnAuthentication(AuthenticationContext context)   
     {        
    IAccountRepository acc = DependencyResolver.Current.GetService<IAccountRepository>();       
     bool access = acc.GetAccess();        
    if (!access)            
    context.Result = new HttpUnauthorizedResult();    
    }    
    public void OnAuthenticationChallenge(AuthenticationChallengeContext context)    
    {        
    if (context.Result == null || context.Result is HttpUnauthorizedResult)        
    {                
    context.Result = new RedirectToRouteResult(new RouteValueDictionary   {  
     {"controller", "Applications"},                   
     {"action",  "AccessDenaid"}                
    });       
     }    
    }
    }

    and check his user rights in OnAuthentication.

    Then I will have to place the [AuthorizeClass1] attribute on each ActionResult method, which returns the main page, not a partial one.

    public class HomeController
    {
    
     
     public ActionResult PartialChtototTam()
     {
     
    	return View();
     }
     
     
     [AuthorizeClass1]
     public ActionResult List()
     {
    	return View();
     }
     
     [AuthorizeClass1]
     public ActionResult Index()
     {
    	return View();
     }

    I do not like this decision.

    Can I somehow place [AuthorizeClass1] over the controller class, and then somehow process only the ActionResults I need so that all sorts of shtmls in which modal forms and all kinds of listboxes do not fly into it?

    ps:I hope you got what I meant.

    Thursday, August 1, 2019 6:30 AM

Answers

  • User1520731567 posted

    Hi Koss86,

    Do you propose to split the controller into two controllers?

    You could do that.

    And how to cache:

    bool access = acc.GetAccess ();

    I find your sql is not complex,unless the amount of data is huge,or data modification frequency is not high,you could use cache.

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 9, 2019 9:53 AM

All replies

  • User753101303 posted

    Hi,

    If I understood you could write your Authorize attribute so that it skips the check if an AllowAnonymous attribute is found (see the SkipAuthorization method at  https://github.com/aspnet/AspNetWebStack/blob/master/src/System.Web.Http/AuthorizeAttribute.cs ).

    This way you can use Authorize at the controller level (or even as a global filter) and then use AllowAnoymous just where needed.

    Thursday, August 1, 2019 9:02 AM
  • User-194957375 posted
    [AuthorizeClass1]
    public class HomeController
    {
    
    [AllowAnonymous]
    [HttpPost]
     public ActionResult CallAjax()
     {
     
    	return new HTTPNotFoundResult();
     }
    [AllowAnonymous]
     public ActionResult PartialChtototTam_1()
     {
     
    	return View();
     }
     [AllowAnonymous]
     public ActionResult PartialChtototTam_2()
     {
     
    	return View();
     }
    //...
    [AllowAnonymous]
     public ActionResult PartialChtototTam120()
     {
     
    	return View();
     }
     
     
     public ActionResult List()
     {
    	return View();
     }
     
     
     public ActionResult Index()
     {
    	return View();
     }
     }

    So use it? I have a lot of methods ActionResult. Above each you need to indicate this attribute ( [AllowAnonymous] )?

    Thursday, August 1, 2019 11:42 AM
  • User753101303 posted

    What is needed by most of your methods? Basically you define what you need most at the controller level and then tell which actions should not follow this general rule.

    It's a bit hard to comment as I known nothing about your approach but it seems a bit strange to have ajax calls or partial views not requiring the same access level than the controller ( or at least to have about 50% of each of them in the same controller ?). Try to see if you can really can't keep controllers having a  general rule and 0 to a couple of methods not using the controller level access rule.

    Saturday, August 3, 2019 1:33 PM
  • User-194957375 posted

    In my method 

    public void OnAuthentication(AuthenticationContext context)   
     {        
    IAccountRepository acc = DependencyResolver.Current.GetService<IAccountRepository>();       
     bool access = acc.GetAccess();        
    if (!access)            
    context.Result = new HttpUnauthorizedResult();    
    }  

    acc.GetAccess() contains sql-expression 

    select *
    
    From Table_access
    
    Where userName = @CurrentUser

    Therefore, I need the sql-expression to be executed only for the main page. 

    Having an extra method in every controller method is expensive.

    What I showed in the first post is so far the best option. 

    Monday, August 5, 2019 6:25 AM
  • User753101303 posted

    You  could cache this information rather than loading it from the db each time.

    If having both  in a single controller quite a number of authenticated and anonymous actions, see maybe if it couldn't be reorganized. I always try to have a controller mostly dedicated to authenticated or anonymous users, with at most a couple of other actions  when really needed...

    Monday, August 5, 2019 7:40 AM
  • User-194957375 posted

    Do you propose to split the controller into two controllers?

    [AuthorizeClass1]
    public class HomeController:Controller
    {
     
    	 public ActionResult List()
    	 {
    		return View();
    	 }
    	 
    	 
    	 public ActionResult Index()
    	 {
    		return View();
    	 }
    	 
     }
     
     public class HomeControllerAdditional:Controller
    {
     
    [HttpPost]
     public ActionResult CallAjax()
     {
     
    	return new HTTPNotFoundResult();
     }
    
     public ActionResult PartialChtototTam_1()
     {
     
    	return View();
     }
    
     public ActionResult PartialChtototTam_2()
     {
     
    	return View();
     }
    //...
    
     public ActionResult PartialChtototTam120()
     {
     
    	return View();
     }
     }

    And how to cache:

    bool access = acc.GetAccess ();

    How to keep it relevant?

    Monday, August 5, 2019 9:08 AM
  • User1520731567 posted

    Hi Koss86,

    Do you propose to split the controller into two controllers?

    You could do that.

    And how to cache:

    bool access = acc.GetAccess ();

    I find your sql is not complex,unless the amount of data is huge,or data modification frequency is not high,you could use cache.

    Best Regards.

    Yuki Tao

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 9, 2019 9:53 AM
  • User-194957375 posted

    Ok! Same question. ) I want to cache the request when the page load. When you first visit the site - no.

    event any page load  on js (code in _Layout.cshtml ):

    $(document).ready(function () {
    LoadUrl();
    
    });
    
    function LoadUrl()
    {
    try {
    $.ajax({
    type: "POST",
    url: getBaseUrl("Applications") + '/LoadPage',
    data: { load_url: window.location.href },
    
    });
    } catch (err) { }
    }

    it is not reliable, I want on the server.

    Monday, August 12, 2019 6:27 AM
  • User-194957375 posted

    conclusion: what I want to do can only be divided into 2 controllers.

    Monday, August 12, 2019 6:29 AM