【问题标题】:Automatically get access_token in MVC client (IdentityServer)在 MVC 客户端(IdentityServer)中自动获取 access_token
【发布时间】:2020-08-22 08:52:39
【问题描述】:

我像“创建 MVC 客户端”一样编写“MVC 客户端”https://identityserver4.readthedocs.io/en/latest/quickstarts/2_interactive_aspnetcore.html#creating-an-mvc-client 我的主要目标是在 access_token 过期时使用 refresh_token 获得新的。 我需要它不是用于 API 访问,而是用于“MVC 客户端”身份验证/授权。

所以,在“MVC 客户端”问题重定向到 IdentityServer 到其登录页面(http://localhost:5000/connect/authorize?client_id=mvc&redirect_uri=bla,bla,bla)之前,我想只是拦截它并发送而不是只获取新的 access_token(带有 refresh_token)而无需用户需要输入他的凭据。

因此,我只需要在“MVC 客户端”确定 access_token 不再有效并尝试重定向到 IdentityServer 登录之前获取任何事件。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";

        })                
            .AddCookie("Cookies", options => {
                options.Cookie.Name = "MyCookie";
                options.Cookie.MaxAge = new TimeSpan(0, 0, 60);
                options.ExpireTimeSpan = new TimeSpan(0, 0, 60);
                options.SlidingExpiration = false;

                //options.Cookie.s ExpireTimeSpan   = new TimeSpan(0, 0, 1);


                options.Events = new Func<CookieAuthenticationEvents>(() =>
                {
                    var cookieAuthenticationEvents = new CookieAuthenticationEvents( );

                    var f = cookieAuthenticationEvents.OnRedirectToLogin;
                    var f1 = cookieAuthenticationEvents.OnValidatePrincipal;
                    var f2 = cookieAuthenticationEvents.OnSignedIn;

                    cookieAuthenticationEvents.OnRedirectToLogin = ( context ) =>
                    {
                        return f(context);
                    };
                    cookieAuthenticationEvents.OnValidatePrincipal = ( context ) =>
                    {
                        return f1(context);
                    };
                    cookieAuthenticationEvents.OnSignedIn = ( context ) =>
                    {
                        return f2(context);
                    };

                    return cookieAuthenticationEvents;
                }
                )( );
            })
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;

                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code";       
                options.SaveTokens = true;

                options.Scope.Add("email");
                options.Scope.Add("api1");
                options.Scope.Add("offline_access");


      //          options.Events = new Func<>


            options.Events = new Func<OpenIdConnectEvents>(() =>
            {
                var openIdConnectEvents = new OpenIdConnectEvents( );
                var f = openIdConnectEvents.OnAuthenticationFailed;
                var f1 = openIdConnectEvents.OnAccessDenied;
                var f2 = openIdConnectEvents.OnTokenValidated;
                var f3 = openIdConnectEvents.OnAccessDenied;
                openIdConnectEvents.OnAuthenticationFailed = ( context ) =>
                {
                    return f(context);
                };
                openIdConnectEvents.OnAccessDenied = ( context ) =>
                {
                    return f1(context);
                };
                openIdConnectEvents.OnTokenValidated = ( context ) =>
                {
                    return f2(context);
                };
                openIdConnectEvents.OnAccessDenied = ( context ) =>
                {
                    return f3(context);
                };

                return openIdConnectEvents;
            }
                )( );

            });
    }

"return f3(context);" 的每一行上,我都设置了断点,并期待在进入 IdentityServer 的登录页面之前点击它 - 不走运。

这是客户端配置。

                new Client
            {
                ClientId = "mvc",
                ClientSecrets = { new Secret("secret".Sha256()) },

                AllowedGrantTypes = GrantTypes.Code,
                RequireConsent = false,
                RequirePkce = true,

                // where to redirect to after login
                RedirectUris = { "http://localhost:5002/signin-oidc" },

                // where to redirect to after logout
                PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    "api1"
                },

                AlwaysIncludeUserClaimsInIdToken = true,
                AllowOfflineAccess = true,

                AccessTokenLifetime = 150,
                AuthorizationCodeLifetime = 150,
                UserSsoLifetime = 150
            }

如何做 - 自动刷新令牌,无需用户交互以进行 MVC 客户端身份验证(不适用于 API 访问)

【问题讨论】:

    标签: asp.net-mvc authentication identityserver4 access-token refresh-token


    【解决方案1】:

    我找到了解决方案。这里是: https://github.com/leastprivilege/AspNetCoreSecuritySamples/tree/aspnetcore21/AutomaticTokenManagement

    这里的重点是重写这个方法

    public override async Task ValidatePrincipal ( CookieValidatePrincipalContext context )
    

    来自班级

    Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents
    

    【讨论】:

      猜你喜欢
      • 2018-11-21
      • 2021-03-30
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多