【问题标题】:IdentityServer 4 WsFederation - How to get access token for calling APIIdentityServer 4 WsFederation - 如何获取调用 API 的访问令牌
【发布时间】:2021-03-15 10:59:17
【问题描述】:

我正在使用带有 Ws-Federation 插件的 Identity Server 4。 Identity Server 配置为连接到 Azure AD 进行身份验证。以下是来自 Identity Server 项目的相关代码:

public void ConfigureServices(IServiceCollection services)
        {
            var rsaCertificate = new X509Certificate2("rsaCert.pfx", "1234");

            services.AddRazorPages();
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<User, IdentityRole>(options =>
            {
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(2);
                options.Lockout.MaxFailedAccessAttempts = 3;
            })
            .AddDefaultUI()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddUserStore<CustomUserStore>()
            .AddUserManager<CustomUserManager>()
            .AddDefaultTokenProviders();

            services.AddTransient<IUserStore<User>, CustomUserStore>();
            services.AddTransient<IEmailSender, EmailSender>();

            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;

                // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
                options.EmitStaticAudienceClaim = true;
            })
            .AddSigningCredential(rsaCertificate)
            .AddInMemoryIdentityResources(IdentityConfig.IdentityResources)
            .AddInMemoryApiScopes(IdentityConfig.ApiScopes)
            .AddInMemoryClients(IdentityConfig.Clients)
            .AddAspNetIdentity<User>()
            .AddWsFederationPlugin(options =>
            {
                options.Licensee = "Licensee";
                options.LicenseKey = "LicenseKey";
            })
            .AddInMemoryRelyingParties(new List<RelyingParty>());

            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
            })
            .AddWsFederation(options =>
            {
                options.Wtrealm = "Azure AD App Id";
                options.MetadataAddress = "WSFed metadata URL from Azure AD App";
                options.Events.OnSecurityTokenValidated = SecurityTokenValidated;
            })
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(IdentityConfig.SessionTimeoutInMinutes);
                options.SlidingExpiration = true;
                options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
            });
        }

我有一个受 JWT 不记名身份验证保护的 API,它连接到同一个身份服务器。 API 中的相关代码(请注意 https://localhost:5001 是 Identity Server 运行所在的地址):

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

            services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = "https://localhost:5001";

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false
                };
            });
        }

我也有一个 MVC 客户端,它连接到同一个身份服务器。我能够成功地从 MVC 客户端对用户进行身份验证。现在,我想做的是从 MVC 客户端调用 API 项目中受保护的 API 端点。我还没有找到任何方法来获取调用受保护 API 所需的 access token。 MVC客户端的相关代码:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.Cookie.Name = "aspnetcorewsfed";
                options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
                options.SlidingExpiration = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(Configuration.GetValue<int?>("SessionTimeoutInMinutes") ?? 15);
            })
            .AddWsFederation(options =>
            {
                options.MetadataAddress = "https://localhost:5001/wsfed"; // Address of the Identity Server
                options.RequireHttpsMetadata = false;

                options.Wtrealm = "mvc"; // ClientId registered in Identity Server

                options.CallbackPath = "/";
                options.SkipUnrecognizedRequests = true;
            });
        }

Identity Server 网站上的文档描述了如何访问受保护的 API,如 here 所示。但这是使用 OpenIdConnect。由于我使用的是 WsFederation,因此我不知道如何获取访问令牌或刷新令牌。使用 WsFed 是否无法刷新令牌?

任何人都可以为我指出正确的方向吗?

【问题讨论】:

    标签: asp.net-core azure-active-directory identityserver4 ws-federation


    【解决方案1】:

    在 MVC 客户端中使用 OpenIdConnect 而不是 WsFed。将 MVC 客户端的 Startup.cs 中的代码更改为以下内容:

    services.AddAuthentication(options =>{
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    }).AddCookie("Cookies").AddOpenIdConnect("oidc", options =>{
        options.Authority = "https://localhost:5001";
        options.ClientId = "mvc-openid";
        options.ClientSecret = "secret";
        options.ResponseType = "code";
        options.SaveTokens = true;
    });
    

    Identity Server中对应的客户端注册应该是:

    new Client {
        ClientId = "mvc-openid",
        ClientSecrets = {
          new Secret("secret".Sha256())
        },
        AllowedGrantTypes = GrantTypes.Code,
        RedirectUris = {
          "https://localhost:6001/signin-oidc"
        },
        AllowedScopes = new List < string > {
          IdentityServerConstants.StandardScopes.OpenId,
          IdentityServerConstants.StandardScopes.Profile,
          "api"
        }
    }
    

    https://localhost:5001 是身份服务器地址,https://localhost:6001 是 MVC 客户端地址。

    访问API的访问令牌可以这样获取:

    var accessToken = await HttpContext.GetTokenAsync("access_token");

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-11
      • 2017-02-14
      • 1970-01-01
      • 2013-03-02
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      相关资源
      最近更新 更多