【问题标题】:Implicit Bearer flow for swagger asp..net core 3.1swagger asp..net core 3.1的隐式承载流
【发布时间】:2020-03-25 08:36:02
【问题描述】:

有没有办法自动将不记名令牌放入 Swagger 中的每个请求? 我不想在应该与身份交互的地方使用 oauth 隐式流。

我想为我的 api 提供一个端点,它可以获取访问令牌并自动将其放入每个请求。

【问题讨论】:

    标签: c# asp.net-core swagger


    【解决方案1】:

    在你的 startup.s 类中:

    // prevent from mapping "sub" claim to nameidentifier.
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
    
    var identityUrl = configuration.GetValue<string>("IdentityUrl");
    
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.Authority = identityUrl;
        options.RequireHttpsMetadata = false;
        options.Audience = "demo_api";
    });
    

    SwaggerGen

        services.AddSwaggerGen(options =>
        {
          ...
            options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
           {
                Type = SecuritySchemeType.OAuth2,
                Flows = new OpenApiOAuthFlows
                {
                    Implicit = new OpenApiOAuthFlow
                    {
                        AuthorizationUrl = new Uri($"{configuration.GetValue<string>("IdentityUrl")}/connect/authorize"),
                        TokenUrl = new Uri($"{configuration.GetValue<string>("IdentityUrl")}/connect/token"),
                        Scopes = new Dictionary<string, string>()
                        {
                            { "api1", "Demo API - full access" }
                        }
                    }
                }
            });
    

    操作过滤器

    options.OperationFilter<AuthorizeCheckOperationFilter>();
    

    实现

    public class AuthorizeCheckOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() ||
                               context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
    
            if (!hasAuthorize) return;
    
            var unauthorizedHashCode = HttpStatusCode.Unauthorized.GetHashCode().ToString();
            var unauthorizedDescription = HttpStatusCode.Unauthorized.ToString();
    
            var forbiddenHashCode = HttpStatusCode.Forbidden.GetHashCode().ToString();
            var forbiddenDescription = HttpStatusCode.Forbidden.ToString();
    
            operation.Responses.TryAdd(unauthorizedHashCode, new OpenApiResponse { Description = unauthorizedDescription });
            operation.Responses.TryAdd(forbiddenHashCode, new OpenApiResponse { Description = forbiddenDescription });
    
            var oAuthScheme = new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
            };
    
            operation.Security = new List<OpenApiSecurityRequirement>
            {
                new OpenApiSecurityRequirement
                {
                    [ oAuthScheme ] = new [] { "api1" }
                }
            };
    
        }
    }
    

    使用这个

    // Keep both UseAuthentication and UseAuthorization IN THIS ORDER
    app.UseAuthentication();
    app.UseAuthorization();
    

    使用 Swagger

    app.UseSwagger(c =>
            {
                c.RouteTemplate = "swagger/{documentName}/swagger.json";
            });
            app.UseSwaggerUI(s =>
            {
                s.SwaggerEndpoint("/swagger/v1/swagger.json", "Your awesome project name");
    
                s.OAuthAppName("My API - Swagger");
                s.OAuthClientId("client");
    
                // Should match the client RedirectUrl in the IdentityServer
                s.OAuth2RedirectUrl("https://localhost:5001/swagger/oauth2-redirect.html");
            });
    

    你的控制器

    [Authorize]
    [ApiController]
    [Route("api/[controller]")] // TODO: Take care of the versioning
    public class IndentityController : ControllerBase
    {
        ...
    

    现在在 IdentityServer 项目中。 ApiResources:

    public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("api1", "My API")
            };
        }
    

    最后,您的客户端应该如下所示:

    new Client
    {
        ClientId = "client",
        AllowedGrantTypes = GrantTypes.Implicit,
        RedirectUris = { "https://localhost:5001/swagger/oauth2-redirect.html" },
        AllowedScopes = { "api1" },
        AllowAccessTokensViaBrowser = true,
        RequireConsent = false
    }
    

    如需完整源代码,请查看eShopOnContainers repo

    祝你好运:)

    【讨论】:

      【解决方案2】:

      下一个代码对我有用

      services.AddSwaggerGen(c =>
              {
                  c.SwaggerDoc("v2", new Microsoft.OpenApi.Models.OpenApiInfo
                  {
                      Version = "v2",
                      Title = "PRJ API",
                      Description = "PRJ Web API",
                  });
      
                  if (oktaIssuer != null)
                  {
                      c.AddSecurityDefinition("Okta", new OpenApiSecurityScheme
                      {
                          Type = SecuritySchemeType.OAuth2,
                          Scheme = "Bearer",
                          In = ParameterLocation.Header,
                          Name = "Authorization",
                          Flows = new OpenApiOAuthFlows
                          {
                              Implicit = new OpenApiOAuthFlow
                              {
                                  AuthorizationUrl = new Uri($"{oktaIssuer}/v1/authorize"),
                                  Scopes = new Dictionary<string, string>
                                  {
                                      { "profile", "Access profile" },
                                      { "email", "Email"},
                                      { "openid", "OpenID"}
                                  }
                              }
                          }
                      });
      
                      c.AddSecurityRequirement(new OpenApiSecurityRequirement
                      {
                          {
                              new OpenApiSecurityScheme
                              {
                                  Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Okta" },
                                  Scheme = "oauth2",
                                  Name = "Bearer",
                                  In = ParameterLocation.Header
                              },
                             
                              new string[] {}
                          }
                      });
                      c.OperationFilter<AuthorizeCheckOperationFilter>();
                  }
      

      这些字符串也必须相同!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-22
        • 1970-01-01
        • 2020-04-03
        • 1970-01-01
        相关资源
        最近更新 更多