最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - AccessToken is null when using OpenIdConnect - Stack Overflow

programmeradmin5浏览0评论

I have a Blazor server-side app and in Startup.cs I have the following:

services.AddSingleton<ITicketStore, CookieMemoryTicketStore>();
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
        .Configure<ITicketStore>((options, store) =>
        {
            options.ExpireTimeSpan = TimeSpan.FromDays(14);
            options.SlidingExpiration = true;
            options.SessionStore = store;
        });

I use a ITicketStore implementation to store the cookies using MemoryCache. and then the authentication set up:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Authority = "authority";
    options.ClientId = "clientid";
    options.ClientSecret = "clientsecret";
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.ResponseMode = OpenIdConnectResponseMode.FormPost;
    options.GetClaimsFromUserInfoEndpoint = true;
    options.MapInboundClaims = false;
    options.SaveTokens = true;
    options.UseTokenLifetime = false;
    options.UseSecurityTokenValidator = true;
    options.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    options.Scope.Add(OpenIdConnectScope.Email);
    options.Scope.Add(OpenIdConnectScope.OfflineAccess);
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role"
    };
});
services.AddAuthorizationCore();

And in my _Host.cshtml I do:

var tokens = new InitialApplicationState
{
    AccessToken = await HttpContext.GetTokenAsync(Token.Access),
    IdToken = await HttpContext.GetTokenAsync(Token.Id),
    RefreshToken = await HttpContext.GetTokenAsync(Token.Refresh),
};

And the InitialApplicationState is then used in App.razor.

And during my login process (on login redirect from the auth provider), I start with:

var oidcOptions = new OidcClientOptions
{
    Authority = "issuer",
    ClientId = "clientid",
    LoadProfile = false,
    Scope = StandardScopes.OpenId
};

var client = new OidcClient(oidcOptions);
var state = await client.GetUserInfoAsync(tokenProvider.AccessToken, ct);

Using the above everything works fine for a few hours. Then all of a sudden, when the user is automatically authenticated (his authenication cookies are still stored in the browser), the call to GetUserInfoAsync fails with an exception because tokenProvider.AccessToken is null.

The only workaround so far is to delete all the site cookies and then authentication/authorization works again.

NOTE

The project was originally created with NET5 but the target framework currently used in NET8. However, it does not use the NET8-specific features.

Has anyone encountered this problem? Is the above code missing some steps?

UPDATE

When I do (in _Host.cshtml):

var authState = await HttpContext.AuthenticateAsync();

I get Failure with the message 'Unprotect ticket failed' and it enters an infinite loop refreshing the page.

I added the following cookie event:

options.Events.OnSignedIn = context =>
{
    context.Properties.IsPersistent = true;
    return Task.CompletedTask;
};

The Properties has 11 items and there I can see the access and refresh tokens correctly.

发布评论

评论列表(0)

  1. 暂无评论