How to override AcquireTokenSilent?

Kaio Labre 1 Reputation point
2022-08-12T06:29:27.453+00:00

Hi all,

I have a monolith application based on ASP.NET MVC 4.7.2 that I have just migrated to AD authentication / Authorization following this guide: https://learn.microsoft.com/en-us/learn/modules/msgraph-build-aspnetmvc-apps/5-exercise-add-auth

Everything works, I know the token expires in 1 hour and the Msal library refreshes the token automatically. Although, the token sometimes happens to expire right during a POST action request and the AD returns to the same form post action URL as a GET request which then returns a 404 because the view for that post action doesn't exist.

My goal is to either refresh the token and go back to the previous view with a message, or override the callback action of the AcquireTokenSilent to make sure that we don't end up on the 404 result.

// view  
  
    @using (Html.BeginForm("InsertBA", "TestPoint", FormMethod.Post, new { @class = "", role = "form", id = "" }))  
    {  
        @Html.AntiForgeryToken()  
        // .., Form fields and submit button  
    }  
  
  
// controller  
  
       public ActionResult BA() // has a form that posts to SubmitBA  
        {  
            return View();  
        }  
          
        public ActionResult SubmitBA(BAViewModel model)  
        {  
           // business logic  
  
            return View(model); // has a form that POSTs to InsertBA  
        }  
  
       [HttpPost]  
        public ActionResult InsertBA(BAViewModel model)  
        {  
            // Business logic  
            // ....  
            return View("BA", model);  
        }  

The action log:

230600-image.png

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,246 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,389 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 55,041 Reputation points
    2022-08-12T21:31:02.19+00:00

    you don't explain your use case or your setup.

    AquireTokenSilent works by storing a the refresh token in a cache (if a web farm, this should be a distributed cache or it may not be found). On a call to AquireTokenSilent the refresh token is retrieved from the cache, then used in a call to the OAUTH server to get an access token. If not found, or expired, then a new refresh token is required.

    to get an id and refresh token from the OAUTH server, the user must login again to the OAUTH server. The AquireTokenSilent() code redirects to the OAUTH server requesting a token. The user logins to the OAUTH server and the OAUTH server redirects back to the original website, which then store the tokens and request a new access token with them (also updating the cache). If the OAUTH servers login cookie has not expired, the OAUTH server will not need to ask for credentials, and can redirect back silently.

    So in your case on a POST request, the refresh token is not found (maybe a recycle) or is expired. This causes a redirect to the OAUTH server losing the POST data, After authentication, the OAUTH server redirects back to web site. The web site stores the token and redirects to the original url. A redirect is of course alway a GET. Your action log is missing the GETS to the OAUTH server. If you look at the browser network trace you can see them.

    Your application code will need to handle this case. You can implement a GET method for the post pages that displays message for instance. These actions could be a simple redirect to a message page, or set up the original page that was doing the post with a message,


  2. Bruce (SqlWork.com) 55,041 Reputation points
    2022-08-15T21:32:15.393+00:00

    your use case is still not clear.

    the sample you link to use cookie authentication and AD oauth. in that sample, the token is only used to build the claims in authentication cookie. the authentication cookie expiration is based on the oauth token expiration (sliding window is not supported).

    when the authentication cookie expires (the browser does send it to the server), the mvc server will redirect to the auth server to get a new token and build a new authentication cookie. the return url is used to determine where to redirect after login. when your define the CookeAuthenicationOptions to UseCookeAuthenication, you can replace the redirect logic (the sample just uses the defaults)

           Provider = new CookieAuthenticationProvider    
           {   
       ...    
                  OnApplyRedirect = (context) =>   
                  {   
                       // look at query string return url and make decision where to go instead   
                       context.Response.Redirect(redirectUrl);   
                  }   
           }   
      
    

    the sample also contains code to store the token in a cache to use for graph api calls (not authentication). in this case an access and refresh tokens are stored in the cache, and AquireTokenSilent() is called to get an access token. it will use the refresh token to get a new access token is required. but this is all outside site authentication.

    note: when not using oauth, a sliding windows for cookie authentication is often used. this causes the cookie expiration to be updated half way through expiration. but this is not supported with oauth.

    0 comments No comments