问题描述
更新 2:如果我从这里更改我的控制器授权标签
UPDATE 2: If I change my controller Authorize tag from this
[Authorize]
到这里
[Authorize(Roles = "Read")]
然后我得到范围选择的复选框,并且 ajax 令牌请求包含正确的范围并成功完成.然而,我仍然以红色感叹号结束.看起来 Swagger 或 Swashbuckle 要求角色与范围定义匹配?使用 Swashbuckle 时是否可以使用未定义角色的应用程序流?如果是这样,您如何使其工作?我是否必须在操作过滤器类中手动设置范围?如果在 Authorize 标签中不列出角色就无法使用 Swashbuckle,那么我需要知道如何在 IdentityServer3 中分配客户端角色.
then I get the checkbox for scope selection and the ajax token request contains the correct scope and completes successfully. I still end up with a red exclamation mark however. It looks like Swagger or Swashbuckle is requiring that the roles match the scope definitions? Is it possible to use the application flow with no Roles defined when using Swashbuckle? And if so how do you get that to work? Do I have to manually set the scope in the operation filter class? If it's not possible to use Swashbuckle without listing Roles in the Authorize tag, then I need to know how to assign clients roles in IdentityServer3.
更新 3如果我将操作过滤器更改为类似的内容,则会出现范围,但在选择范围并单击授权后,页面会重新加载.ajax授权先发送成功.这个比较近了,但是授权还是不粘(这里不知道用什么词,但是stick好像总结了一下.)如何获取授权粘贴?
UPDATE 3 If I change the Operation Filter to something like this the scope appears, but after selecting the scope and clicking on Authorize, the page just reloads. The ajax authorization was sent successfully first. This is closer, but the authorization still doesn't stick (not sure what term to use here, but stick seems to sum it up.) How do I get the authorization to 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);
}
}
原帖我正在尝试配置 Swashbuckle 以允许客户端测试受 OAuth2 客户端凭据流保护的 REST 服务.切换永远不会出现在页面上,不是吗?,但我确实看到了一个带有感叹号的红色圆圈,告诉我资源不受保护.我正在使用 nuget 包 Swashbuckle.Core 版本 5.4.0.Enable Oauth2 client credentials flow in Swashbuckle 的答案似乎遵循什么我已经完成了,并且已经逐字使用了 AssignOAuth2SecurityRequirements 类.我没有注入任何 javascript 并且不相信我必须这样做,因为我的授权方案是相当标准的.当我删除控制器上的 Authorize 关键字时,该方法在 Swagger UI 中不再有红色感叹号,我希望这意味着我已经接近了,但我没有找到丢失的链接.由于此流程是应用程序"并且我只有一个范围,因此我想确保它看起来配置正确并且 clientSecret 加载到正确的位置.
Original Post I'm trying to configure Swashbuckle to allow clients to test a REST service that is protected by an OAuth2 client credentials flow. The toggle never appears on the page, should it?, but I do get a red circle with an exclamation mark telling me the resource is not protected. I'm using the nuget package Swashbuckle.Core Version 5.4.0. The answer here Enable Oauth2 client credentials flow in Swashbuckle seems to follow what I've done, and have used the AssignOAuth2SecurityRequirements class verbatim. I haven't injected any javascript and don't believe I have to since my authorization scheme is fairly standard. When I remove the Authorize key word on the Controller that method no longer has the red exclamation in the Swagger UI which I'm hoping means I'm close, but I'm not finding the missing link. Since this Flow is "application" and I only have one scope I wanted to make sure that it looks configured correctly and the clientSecret is loaded in the correct spot.
更新 1我已经能够调试 AJAX 调用并且可以看到未设置范围,因此未在请求中发送.为什么没有设置范围?为什么我没有选择范围的复选框?
这是我的 SwaggerConfig.cs
Here is my SwaggerConfig.cs
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "waRougeOneApp");
c.OAuth2("oauth2")
.Description("OAuth2 Client Credentials Grant Flow")
.Flow("application")
.TokenUrl("https://securitydev.rougeone.com/core/connect/token")
.Scopes(scopes =>
{
scopes.Add("Read", "Read access to protected resources");
});
c.IncludeXmlComments(GetXmlCommentsPath());
c.UseFullTypeNameInSchemaIds();
c.DescribeAllEnumsAsStrings();
c.OperationFilter<AssignOAuth2SecurityRequirements>();
})
.EnableSwaggerUi(c =>
{
c.EnableOAuth2Support(
clientId: "client_id",
clientSecret: "client_secret",
realm: "swagger-realm",
appName: "Swagger UI"
);
});
}
protected static string GetXmlCommentsPath()
{
return System.String.Format(@"{0}bin\waRougeOne.xml", System.AppDomain.CurrentDomain.BaseDirectory);
}
}
AssignOAuth2SecurityRequirements 类是
And the AssignOAuth2SecurityRequirements class is
public class AssignOAuth2SecurityRequirements : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var authorized = apiDescription.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>();
if (!authorized.Any()) return;
if (operation.security == null)
operation.security = new List<IDictionary<string, IEnumerable<string>>>();
var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
{
{"oauth2", Enumerable.Empty<string>()}
};
operation.security.Add(oAuthRequirements);
}
}
我一直试图找到一个带有客户端凭据流的工作示例,但没有成功,所以我不能 100% 确定当一切正常时我会看到一个切换按钮.在隐式流程的示例中,如果您将鼠标悬停在红色感叹号上,您会看到列出的授权类型,单击红色感叹号会显示列出的范围选项,您可以在其中选择一个,然后单击授权,它会返回一个蓝色感叹号.
I've been trying to find a working example with a client credentials flow without success, so I'm not 100% sure I'll see a toggle button when everything is working correctly. In the examples for the implicit flow if you hover over the red exclamation circle you see the grant types listed, clicking on the red exclamation circle shows the options for scopes listed out in which you select one and then click authorize and it comes back with a blue exclamation.
对我来说,我从来没有得到一个复选框来选择一个范围,但我只定义了一个范围.我究竟做错了什么?我在调试 swagger ui JavaScript 时发现了这一点,它似乎指向拥有它需要的所有数据?
For me I never get a checkbox to select a scope, but I've only defined one scope. What am I doing wrong? I found this while debugging the swagger ui JavaScript which seems to point to having all the data it needs?
authorizations
:
null
auths
:
Array[1]
0
:
Object
name
:
"oauth2"
type
:
"oauth2"
value
:
Object
description
:
"OAuth2 Client Credentials Grant Flow"
flow
:
"application"
scopes
:
Object
Read
:
"Read access to protected resources"
__proto__
:
Object
tokenUrl
:
"https://security.starrwarrs.com/core/connect/token"
type
:
"oauth2"
__proto__
:
Object
__proto__
:
Object
length
:
1
__proto__
:
Array[0]
推荐答案
解决方案!!最后一部分是最难弄清楚的,我终于在 Chrome 开发者工具的帮助下完成了,该工具在网络标签上显示了一个红色的小 X,显示以下错误消息:
Solution!! The last part was the hardest to figure out, which I finally did with the help of the Chrome Developer tools that showed a little red X on the network tag showing the following error message:
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.
错误消息最终连接了下面的点,在此之前 OAuthComplete 完整的 JavaScript 函数将被调用,但没有令牌.网络选项卡显示此请求没有可用的响应数据",但我会在响应标头中看到 Content-Length,其内容类型为 Json.Fiddler 还显示了看起来像(并且是)格式良好的 JSON 的响应.
The error message finally connected the dots below, until then the on OAuthComplete complete JavaScript function would be called, but with no token. The network tab show "This request has no response data available", but I'd see a Content-Length in the Response headers with a content-type of Json. Fiddler also showed the response which looked like (and was) well formed JSON.
我在这里描述了这个错误 Swagger UI未解析响应,这是由于 IdentityServer3 未正确添加Access-Control-Allow-Origin:http:///localhost:62561" 您可以通过将客户端创建更新为以下内容来强制 IdentityServer3 发送该标头:
I described this error here Swagger UI not parsing reponse which was due to IdentityServer3 correctly not adding a response header of "Access-Control-Allow-Origin:http://localhost:62561" You can force IdentityServer3 to send that header by updating you client creation to be the following:
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"
}
}
AllowedCorsOrigins 是我拼图的最后一块.希望这可以帮助面临同样问题的其他人
The AllowedCorsOrigins was the last piece of my puzzle. Hopefully this helps someone else who is facing the same issue
这篇关于当授权标签不包含角色时,我没有得到范围复选框,Ajax 授权请求也没有发送范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!