Re-authorize persistent login (MVC client) without triggering login UI

前端 未结 2 759
有刺的猬
有刺的猬 2021-01-20 05:42

I am trying to figure out how a server-side client (MVC / ASP.NET Core 2) can query IdentityServer4 to retrieve various claims scopes for a persistent login created in some

相关标签:
2条回答
  • 2021-01-20 05:54

    why not just make the authentication cookie permanent? Here's an other way to do it ... You can then check authentication on the server against the authentication server.

    on the client AddOpenIdConnect :

                    options.Events = new OpenIdConnectEvents {
                        OnRedirectToIdentityProvider = context => {
                            context.Properties.RedirectUri = context.Request.Path;
                            return Task.FromResult(0);
                        },
                        OnTicketReceived = context =>
                        {
                            context.Properties.IsPersistent = true;
                            context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(15);
                            context.Properties.AllowRefresh = true;
    
                            return Task.FromResult(0);
                        }
                    };
    
    0 讨论(0)
  • 2021-01-20 06:06

    The solution is to add a second OIDC auth flow in Setup, intercept the redirect to change the Prompt option to none so that no login prompt is shown, intercept the resulting login_required error message, and trigger that flow in the landing page's PageModel OnGet handler (the client app uses RazorPages).

    One caveat is the handler must set flags so that this is only attempted once, and so that it can detect whether the page is being hit for the first time, or as the return-trip from the login attempt. This is achieved by just dropping a value into the Razor TempData which is just a cookie-based bucket of name-value pairs.

    Add to Setup.cs

    .AddOpenIdConnect("persistent", options =>
    {
        options.CallbackPath = "/signin-persistent";
        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = context =>
            {
                context.ProtocolMessage.Prompt = "none";
                return Task.FromResult<object>(null);
            },
    
            OnMessageReceived = context => {
                if(string.Equals(context.ProtocolMessage.Error, "login_required", StringComparison.Ordinal))
                {
                    context.HandleResponse();
                    context.Response.Redirect("/");
                }
                return Task.FromResult<object>(null);
            }
        };
    
        options.SignInScheme = "Cookies";
        options.Authority = "https://localhost:5000";
        options.RequireHttpsMetadata = true;
        options.ClientId = "example.com.webserver";
        options.ClientSecret = "examplesecret";
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("example.com.identity");
    })
    

    Landing page (Index.cshtml.cs)

    public class IndexModel : PageModel
    {
        private bool PersistentLoginAttempted = false;
        private const string PersistentLoginFlag = "persistent_login_attempt";
    
        public IActionResult OnGet()
        {
            // Always clean up an existing flag.
            bool FlagFound = false;
            if(!String.IsNullOrEmpty(TempData[PersistentLoginFlag] as string))
            {
                FlagFound = true;
                TempData.Remove(PersistentLoginFlag);
            }
    
            // Try to refresh a persistent login the first time an anonymous user hits the index page in this session
            if(!User.Identity.IsAuthenticated && !PersistentLoginAttempted)
            {
                PersistentLoginAttempted = true;
                // If there was a flag, this is the return-trip from a failed persistent login attempt.
                if(!FlagFound)
                {
                    // No flag was found. Create it, then begin the OIDC challenge flow.
                    TempData[PersistentLoginFlag] = PersistentLoginFlag;
                    return Challenge("persistent");
                }
            }
            return Page();
        }
    }
    
    0 讨论(0)
提交回复
热议问题