Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何设置Swashback.AspNetCore.Swagger以使用授权?_C#_Asp.net Core_Swagger_Swagger Ui_Identityserver4 - Fatal编程技术网

C# 如何设置Swashback.AspNetCore.Swagger以使用授权?

C# 如何设置Swashback.AspNetCore.Swagger以使用授权?,c#,asp.net-core,swagger,swagger-ui,identityserver4,C#,Asp.net Core,Swagger,Swagger Ui,Identityserver4,我已经使用swashback.AspNetCore.Swagger记录了我的api,我想使用Swagger ui测试一些具有Authorize属性的资源 应用程序编程接口 响应代码是未经授权的401,那么如何使用swagger对此进行授权 我使用IdentityServer4设置了授权服务器 授权服务器-startup.cs 我想要一个授权按钮,它重定向到登录屏幕,然后授予用户对api资源的访问权限。 是否可以使用asp.net core 1.1 Swagger中间件来实现这一点?或者我需要编

我已经使用swashback.AspNetCore.Swagger记录了我的api,我想使用Swagger ui测试一些具有Authorize属性的资源

应用程序编程接口

响应代码是未经授权的401,那么如何使用swagger对此进行授权

我使用IdentityServer4设置了授权服务器

授权服务器-startup.cs 我想要一个授权按钮,它重定向到登录屏幕,然后授予用户对api资源的访问权限。 是否可以使用asp.net core 1.1 Swagger中间件来实现这一点?或者我需要编写一些javascript从IdentityServer4授权服务器获取令牌吗?
由于我不熟悉身份验证和授权,请提供帮助

我通过向IdentityServer4授权服务器项目添加新客户端解决了这个问题

config.cs
//客户端想要访问资源(又称作用域)
公共静态IEnumerable GetClients()
{
//客户端凭据客户端
返回新列表
{
新客户
{
ClientId=“swaggerui”,
ClientName=“招摇过市用户界面”,
AllowedGrantTypes=GrantTypes.Implicit,
AllowAccessTokensViaBrowser=true,
重定向URI={”http://localhost:49831/swagger/o2c.html" },
PostLogoutRedirectUris={”http://localhost:49831/swagger/" },
AllowedScopes={“api1”}
},
...
...
...
}
}
我在THAAPI中创建了一个招摇过市操作过滤器,以便在需要授权的方法旁边显示一个红色感叹号图标

internal class AuthorizeCheckOperationFilter : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            // Check for authorize attribute
            var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() ||
                               context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();

            if (hasAuthorize)
            {
                operation.Responses.Add("401", new Response { Description = "Unauthorized" });
                operation.Responses.Add("403", new Response { Description = "Forbidden" });

                operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
                operation.Security.Add(new Dictionary<string, IEnumerable<string>>
            {
                { "oauth2", new [] { "api1" } }
            });
            }
        }
    }
内部类AuthorizeCheckOperationFilter:IOperationFilter
{
公共无效应用(操作,操作筛选器上下文)
{
//检查授权属性
var hasaauthorize=context.apiscription.ControllerAttributes().OfType().Any()||
context.apiscription.ActionAttributes().OfType().Any();
如果(已授权)
{
Add(“401”,新响应{Description=“Unauthorized”});
Add(“403”,新响应{Description=“probled”});
operation.Security=newlist();
操作.Security.Add(新字典)
{
{“oauth2”,新[]{“api1”}
});
}
}
}
为了完成我在swagger中通过添加oauth2安全定义和operationfilter配置的授权

startup.cs
services.AddSwaggerGen(c=>
{
c、 大摇大摆的文件(“v1”,新信息
{
Version=“v1”,
Title=“电子商务API”,
Description=“”,
TermsOfService=“无”,
联系人=新联系人{Name=”“,Email=“”,Url=“”},
许可证=新许可证{Name=”“,Url=”“}
});
//为swagger json和ui设置注释路径。
var basePath=PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath=Path.Combine(basePath,“WebApi.xml”);
c、 includexmlcoments(xmlPath);
c、 操作过滤器();
c、 AddSecurityDefinition(“oauth2”,新的OAuth2Scheme
{
Type=“oauth2”,
Flow=“隐式”,
授权URL=”http://localhost:5000/connect/authorize",
令牌URL=”http://localhost:5000/connect/token",
范围=新字典()
{
{“api1”,“我的API”}
}
});
});

正如James在对接受答案的评论中提到的,现在检查Authorize属性的方法略有不同,答案中的
AuthorizeCheckOperationFilter
需要稍微调整,这可能不是100%最好的方法,但是我对下面的代码没有任何问题

internal class AuthorizeCheckOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        context.ApiDescription.TryGetMethodInfo(out var methodInfo);

        if (methodInfo == null)
             return;

        var hasAuthorizeAttribute = false;

        if (methodInfo.MemberType == MemberTypes.Method)
        {
            // NOTE: Check the controller itself has Authorize attribute
            hasAuthorizeAttribute = methodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();

            // NOTE: Controller has Authorize attribute, so check the endpoint itself.
            //       Take into account the allow anonymous attribute
            if (hasAuthorizeAttribute)
                hasAuthorizeAttribute = !methodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any();
            else
                hasAuthorizeAttribute = methodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
        }

        if (!hasAuthorizeAttribute)
            return;

        operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new Response { Description = "Unauthorized" });
        operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new Response { Description = "Forbidden" });

        // NOTE: This adds the "Padlock" icon to the endpoint in swagger, 
        //       we can also pass through the names of the policies in the string[]
        //       which will indicate which permission you require.
        operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
        operation.Security.Add(new Dictionary<string, IEnumerable<string>>
        {
            { "Bearer", new string[] { } }
        });
    }
}
内部类AuthorizeCheckOperationFilter:IOperationFilter
{
公共无效应用(操作,操作筛选器上下文)
{
context.apiscription.TryGetMethodInfo(out-var-methodInfo);
if(methodInfo==null)
返回;
var hasAuthorizeAttribute=false;
if(methodInfo.MemberType==MemberTypes.Method)
{
//注意:检查控制器本身是否具有Authorize属性
hasAuthorizeAttribute=methodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any();
//注意:控制器具有Authorize属性,因此请检查端点本身。
//考虑“允许匿名”属性
if(hasAuthorizeAttribute)
hasAuthorizeAttribute=!methodInfo.GetCustomAttributes(true).OfType().Any();
其他的
hasAuthorizeAttribute=methodInfo.GetCustomAttributes(true).OfType().Any();
}
如果(!hasAuthorizeAttribute)
返回;
operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(),新响应{Description=“Unauthorized”});
operation.Responses.Add(StatusCodes.Status403Forbidded.ToString(),新响应{Description=“Forbidden”});
//注意:这会将“挂锁”图标添加到swagger中的端点,
//我们还可以在字符串[]中传递策略的名称
//这将指示您需要哪些权限。
operation.Security=newlist();
操作.Security.Add(新字典)
{
{“Bearer”,新字符串[]{}
});
}
}

用于.Net核心和Swashback.AspNet
    public class Config
{
    // scopes define the resources in your system
    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("api1", "My API")
        };
    }
   ...
   ...
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,
        ECommerceDbContext context)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000/",
            RequireHttpsMetadata = false,
            AutomaticAuthenticate = true,
            ApiName = "api1"
        });


        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });

        DbInitialiser.Init(context);

        app.UseMvc();
    }
 // clients want to access resources (aka scopes)
        public static IEnumerable<Client> GetClients()
        {
            // client credentials client
            return new List<Client>
            {
                new Client
                {
                    ClientId="swaggerui",
                    ClientName = "Swagger UI",
                    AllowedGrantTypes=GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser=true,
                    RedirectUris = { "http://localhost:49831/swagger/o2c.html" },
                    PostLogoutRedirectUris={ "http://localhost:49831/swagger/" },
                    AllowedScopes = {"api1"}
                },
    ...
    ...
    ...
   }
}
internal class AuthorizeCheckOperationFilter : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            // Check for authorize attribute
            var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() ||
                               context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();

            if (hasAuthorize)
            {
                operation.Responses.Add("401", new Response { Description = "Unauthorized" });
                operation.Responses.Add("403", new Response { Description = "Forbidden" });

                operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
                operation.Security.Add(new Dictionary<string, IEnumerable<string>>
            {
                { "oauth2", new [] { "api1" } }
            });
            }
        }
    }
 services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "ECommerce API",
                    Description = "",
                    TermsOfService = "None",
                    Contact = new Contact { Name = "", Email = "", Url = "" },
                    License = new License { Name = "", Url = "" }
                });

                //Set the comments path for the swagger json and ui.
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                var xmlPath = Path.Combine(basePath, "WebApi.xml");
                c.IncludeXmlComments(xmlPath);

                c.OperationFilter<AuthorizeCheckOperationFilter>();

                c.AddSecurityDefinition("oauth2", new OAuth2Scheme
                {
                    Type = "oauth2",
                    Flow = "implicit",
                    AuthorizationUrl = "http://localhost:5000/connect/authorize",
                    TokenUrl = "http://localhost:5000/connect/token",
                    Scopes = new Dictionary<string, string>()
                    {
                        { "api1", "My API" }
                    }
                });
            });
internal class AuthorizeCheckOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        context.ApiDescription.TryGetMethodInfo(out var methodInfo);

        if (methodInfo == null)
             return;

        var hasAuthorizeAttribute = false;

        if (methodInfo.MemberType == MemberTypes.Method)
        {
            // NOTE: Check the controller itself has Authorize attribute
            hasAuthorizeAttribute = methodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();

            // NOTE: Controller has Authorize attribute, so check the endpoint itself.
            //       Take into account the allow anonymous attribute
            if (hasAuthorizeAttribute)
                hasAuthorizeAttribute = !methodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any();
            else
                hasAuthorizeAttribute = methodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
        }

        if (!hasAuthorizeAttribute)
            return;

        operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new Response { Description = "Unauthorized" });
        operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new Response { Description = "Forbidden" });

        // NOTE: This adds the "Padlock" icon to the endpoint in swagger, 
        //       we can also pass through the names of the policies in the string[]
        //       which will indicate which permission you require.
        operation.Security = new List<IDictionary<string, IEnumerable<string>>>();
        operation.Security.Add(new Dictionary<string, IEnumerable<string>>
        {
            { "Bearer", new string[] { } }
        });
    }
}
internal class AuthorizeCheckOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        context.ApiDescription.TryGetMethodInfo(out var methodInfo);

        if (methodInfo == null)
            return;

        var hasAuthorizeAttribute = false;

        if (methodInfo.MemberType == MemberTypes.Method)
        {
            // NOTE: Check the controller itself has Authorize attribute
            hasAuthorizeAttribute = methodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();

            // NOTE: Controller has Authorize attribute, so check the endpoint itself.
            //       Take into account the allow anonymous attribute
            if (hasAuthorizeAttribute)
                hasAuthorizeAttribute = !methodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any();
            else
                hasAuthorizeAttribute = methodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
        }

        if (!hasAuthorizeAttribute)
            return;

        if (!operation.Responses.Any(r => r.Key == StatusCodes.Status401Unauthorized.ToString()))
            operation.Responses.Add(StatusCodes.Status401Unauthorized.ToString(), new OpenApiResponse { Description = "Unauthorized" });
        if (!operation.Responses.Any(r => r.Key == StatusCodes.Status403Forbidden.ToString()))
            operation.Responses.Add(StatusCodes.Status403Forbidden.ToString(), new OpenApiResponse { Description = "Forbidden" });

        // NOTE: This adds the "Padlock" icon to the endpoint in swagger, 
        //       we can also pass through the names of the policies in the string[]
        //       which will indicate which permission you require.
        operation.Security = new List<OpenApiSecurityRequirement>
        {
            new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        },
                        Scheme = "oauth2",
                        Name = "Bearer",
                        In = ParameterLocation.Header
                    },
                    new List<string>()
                }
            }
        };
    }
}
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSwaggerGen(c =>
    {
        c.OperationFilter<AuthorizeCheckOperationFilter>();
        c.EnableAnnotations();
        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Scheme = "Bearer",
            In = ParameterLocation.Header,
            Name = "Authorization",
            Type = SecuritySchemeType.ApiKey,
            Description = @"JWT Authorization header using the Bearer scheme. \r\n\r\n 
              Enter 'Bearer' [space] and then your token in the text input below.
              \r\n\r\nExample: 'Bearer 12345abcdef'"
        });
    });
    ...
}