C# I';当Authorize标记没有';不包含角色,Ajax授权请求也不发送作用域

C# I';当Authorize标记没有';不包含角色,Ajax授权请求也不发送作用域,c#,oauth-2.0,swagger,swashbuckle,C#,Oauth 2.0,Swagger,Swashbuckle,更新2:如果我从此更改控制器授权标记 [Authorize] 对此 [Authorize(Roles = "Read")] 然后我得到范围选择复选框,ajax令牌请求包含正确的范围并成功完成。然而,我还是以一个红色感叹号结束看起来斯威格或斯威士兰要求角色与范围定义匹配?在使用Swashback时,是否可以在没有定义角色的情况下使用应用程序流?如果是这样的话,您如何使其工作?我必须在operation filter类中手动设置作用域吗?如果不在Authorize标记中列出角色就无法使用Swas

更新2:如果我从此更改控制器授权标记

[Authorize]
对此

[Authorize(Roles = "Read")]
然后我得到范围选择复选框,ajax令牌请求包含正确的范围并成功完成。然而,我还是以一个红色感叹号结束看起来斯威格或斯威士兰要求角色与范围定义匹配?在使用Swashback时,是否可以在没有定义角色的情况下使用应用程序流?如果是这样的话,您如何使其工作?我必须在operation filter类中手动设置作用域吗?如果不在Authorize标记中列出角色就无法使用Swashback,那么我需要知道如何在IdentityServer3中分配客户端角色

更新3 如果我将操作过滤器更改为类似的内容,则会显示范围,但在选择范围并单击“授权”后,页面将重新加载。首先成功发送了ajax授权这更接近了,但授权仍然没有坚持(不确定这里使用什么术语,但stick似乎是对它的总结)。我如何获得坚持的授权?

public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{

    var scopes = new List<string>() { "Read" };

    if (scopes.Any())
    {
        if (operation.security == null)
            operation.security = new List<IDictionary<string, IEnumerable<string>>>();

        var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
        {
            { "oauth2", scopes }
        };

        operation.security.Add(oAuthRequirements);
    }
}

以下是我们已经完成和工作的步骤:

  • 在SwaggerConfig文件中,添加以下设置:
  • 这些属性是:

    • 授权方案的名称(上述示例中的oauth2)
    • 授权方案说明
    • 流量–补助金类型 使用
    • 授权Url–应该是身份管理系统Url的授权Url(例如: )
    • Scopes–作用域名称
    二,。在swagger配置文件中,在swagger ui配置部分下添加以下设置:

    c.EnableOAuth2Support(swaggerConfigurations["ClientId"].ToString(), string.Empty, swaggerConfigurations["RedirectUri"].ToString(), "Swagger", " ", new Dictionary<string, string> { { "resource", GetResources() } });
    
    c.enableAuth2Support(SwaggerConfiguration[“ClientId”].ToString(),string.Empty,SwaggerConfiguration[“RedirectUri”].ToString(),“Swagger”,“”,新字典{{{“resource”,GetResources()});
    
    该方法接受以下参数:

    • clientId–这应该是在安全令牌服务中配置的swagger的客户端ID
    • clientSecret–这应该是客户端密钥。这仅在代码授予类型的情况下才需要
    • 领域–这应该是重定向url(应该是[base address]+swagger/ui/o2c html)
    • appName–这应该是招摇
    • ScopeSeparator–如果只有作用域,则不需要传递该值
    • additionalQueryStringParams–这应该有有效访问群体的列表,并且对应于为其颁发令牌的资源
    三、 在web api项目中创建一个新的操作筛选器,如下所示:

    public class CustomOperationFilter : IOperationFilter
        {              
            public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
            {     
                string clientId = "clientID";
                if (apiDescription != null)
                {
                    var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
    
                    var allowsAnonymous = actFilters.Select(f => f.Instance).OfType<OverrideAuthorizationAttribute>().Any();
                    if (allowsAnonymous)
                    {
                        return; // must be an anonymous method
                    }
                }
    
                if (operation != null)
                {
                    if (operation.security == null)
                    {
                        operation.security = new List<IDictionary<string, IEnumerable<string>>>();
                    }
    
                    var authRequirements = new Dictionary<string, IEnumerable<string>>
                    {
                        { "oauth2", new List<string> { clientId } }
                    };
    
                    operation.security.Add(authRequirements);
                }
            }
        }
    
    公共类CustomOperationFilter:IOperationFilter
    {              
    public void Apply(操作,SchemaRegistry SchemaRegistry,apisdescription apisdescription)
    {     
    字符串clientId=“clientId”;
    如果(apiDescription!=null)
    {
    var actFilters=apiscription.ActionDescriptor.GetFilterPipeline();
    var allowsAnonymous=actFilters.Select(f=>f.Instance).OfType().Any();
    如果(允许匿名)
    {
    return;//必须是匿名方法
    }
    }
    if(操作!=null)
    {
    if(operation.security==null)
    {
    operation.security=新列表();
    }
    var authRequirements=新字典
    {
    {“oauth2”,新列表{clientId}
    };
    操作.安全.添加(authRequirements);
    }
    }
    }
    
    此类将用于将OAuth作用域绑定到各个操作

    四、 在swagger配置文件中添加上述过滤器(参见下面的代码)

    c.操作过滤器();
    
    五、在安全令牌服务中配置客户端ID、密码、重定向Url和资源


    六、 在Web API项目中,如果使用index.html注入特定于API的UI字段/样式,则确保所有javascript代码与index.html文件的Swashback版本保持完整(如位置-

    解决方案中提供的!) 最后一部分是最难理解的,我最终在Chrome开发者工具的帮助下完成了这项工作,该工具在网络标签上显示了一个红色的X,显示了以下错误消息:

    XMLHttpRequest cannot load http://security.RogueOne.com/core/connect/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62561' is therefore not allowed access.
    
    错误消息最终连接到下面的点,直到此时将调用on-OAuthComplete JavaScript函数,但没有标记。network选项卡显示“此请求没有可用的响应数据”,但我会在响应头中看到一个内容长度,其内容类型为Json。Fiddler还显示了类似于(并且是)格式良好的JSON的响应

    我在这里描述了这个错误,它是由于IdentityServer 3没有正确添加“Access Control Allow Origin:”响应头导致的。您可以通过将客户端创建更新为以下内容来强制IdentityServer 3发送该头:

    new Client
    {
        ClientName = "SwaggerUI",
        Enabled = true,
        ClientId = "swaggerUI",
        ClientSecrets = new List<Secret>
        {
            new Secret("PasswordGoesHere".Sha256())
        },
        Flow = Flows.ClientCredentials,
        AllowClientCredentialsOnly = true,
        AllowedScopes = new List<string>
        {
            "Read"
        },
    
        Claims = new List<Claim>
        {
            new Claim("client_type", "headless"),
            new Claim("client_owner", "Portal"),
            new Claim("app_detail", "allow")
        },
        PrefixClientClaims = false
        // Add the AllowedCorOrigins to get the Access-Control-Allow-Origin header to be inserted for the following domains
        ,AllowedCorsOrigins = new List<string>
        {
            "http://localhost:62561/"
            ,"http://portaldev.RogueOne.com"
            ,"https://portaldev.RogueOne.com"
        }
    }    
    
    新客户端
    {
    ClientName=“SwaggerUI”,
    启用=真,
    ClientId=“swaggerUI”,
    ClientSecrets=新列表
    {
    新秘密(“PasswordGoesher.Sha256())
    },
    Flow=Flows.ClientCredentials,
    AllowClientCredentially=true,
    AllowedScopes=新列表
    {
    “读”
    },
    索赔=新名单
    {
    新索赔(“客户类型”、“无头”),
    新索赔(“业主”、“门户”),
    新索赔(“应用程序详情”、“允许”)
    },
    PrefixClientClaims=false
    //添加AllowedCorOriginates以获取访问控制允许为以下域插入源文件头
    ,AllowedCorsOrigins=新列表
    {
    "http://localhost:62561/"
    ,“http:
    
    c.EnableOAuth2Support(swaggerConfigurations["ClientId"].ToString(), string.Empty, swaggerConfigurations["RedirectUri"].ToString(), "Swagger", " ", new Dictionary<string, string> { { "resource", GetResources() } });
    
    public class CustomOperationFilter : IOperationFilter
        {              
            public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
            {     
                string clientId = "clientID";
                if (apiDescription != null)
                {
                    var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
    
                    var allowsAnonymous = actFilters.Select(f => f.Instance).OfType<OverrideAuthorizationAttribute>().Any();
                    if (allowsAnonymous)
                    {
                        return; // must be an anonymous method
                    }
                }
    
                if (operation != null)
                {
                    if (operation.security == null)
                    {
                        operation.security = new List<IDictionary<string, IEnumerable<string>>>();
                    }
    
                    var authRequirements = new Dictionary<string, IEnumerable<string>>
                    {
                        { "oauth2", new List<string> { clientId } }
                    };
    
                    operation.security.Add(authRequirements);
                }
            }
        }
    
    c.OperationFilter<CustomOperationFilter>();
    
    XMLHttpRequest cannot load http://security.RogueOne.com/core/connect/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62561' is therefore not allowed access.
    
    new Client
    {
        ClientName = "SwaggerUI",
        Enabled = true,
        ClientId = "swaggerUI",
        ClientSecrets = new List<Secret>
        {
            new Secret("PasswordGoesHere".Sha256())
        },
        Flow = Flows.ClientCredentials,
        AllowClientCredentialsOnly = true,
        AllowedScopes = new List<string>
        {
            "Read"
        },
    
        Claims = new List<Claim>
        {
            new Claim("client_type", "headless"),
            new Claim("client_owner", "Portal"),
            new Claim("app_detail", "allow")
        },
        PrefixClientClaims = false
        // Add the AllowedCorOrigins to get the Access-Control-Allow-Origin header to be inserted for the following domains
        ,AllowedCorsOrigins = new List<string>
        {
            "http://localhost:62561/"
            ,"http://portaldev.RogueOne.com"
            ,"https://portaldev.RogueOne.com"
        }
    }