IdentityServer3を使用して、クライアント資格情報の付与でWebAPIを保護しています。ドキュメントについては、Swashbuckleを使用していますが、クライアント資格情報(アプリケーション)フローのSwaggerConfigでOauth2を有効にする方法を理解できません。どんな助けでもいただければ幸いです!
私はこれを機能させることができました。答えのほとんどは見つけることができます ここ 。
Client_credentialグラントを機能させるために、変更しなければならない部分がいくつかありました。最初の部分は、EnableSwaggerおよびEnableSwaggerUi呼び出しにあります。
_config.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "sample api");
c.OAuth2("oauth2")
.Description("client credentials grant flow")
.Flow("application")
.Scopes(scopes => scopes.Add("sampleapi", "try out the sample api"))
.TokenUrl("http://authuri/token");
c.OperationFilter<AssignOAuth2SecurityRequirements>();
}).EnableSwaggerUi(c =>
{
c.EnableOAuth2Support("sampleapi", "samplerealm", "Swagger UI");
});
_
ここでの重要な変更は.Flow("application")
です。_.TokenUrl
_の代わりに_.AuthorizationUrl
_呼び出しも使用しました。これは、設定されている特定の認証スキームによって異なります。
少し違う_AssignOAuth2SecurityRequirements
_クラスも使用しました
_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);
}
}
_
これは、認証スイッチを表示するのに十分なはずです。私にとってのもう1つの問題は、デフォルトの認証ダイアログが設定されているため、ユーザーがスコープを選択してから[承認]をクリックするだけで済むことでした。私の場合、認証の設定方法が原因でこれは機能しませんでした。 swagger-oauth.jsスクリプトでダイアログを書き直して、SwaggerUIに挿入する必要がありました。
これをすべて機能させるのにもう少し苦労しましたが、多くの忍耐力の後で、JavaScriptをSwaggerUIに挿入しなくても機能するソリューションを見つけました。注:私の問題の一部は、優れた製品であるIdentityServer3を使用したことが原因である可能性がありますが、構成の問題について知らなかっただけです。
私の変更のほとんどは上記の請求書の回答に似ていますが、操作フィルターが異なります。私のコントローラーでは、すべてのメソッドに次のような役割のないAuthorizeタグがあります。
[Authorize]
// Not this
[Authorize(Roles = "Read")] // This doesn't work for me.
Authorizeタグにロールが定義されていない場合、OperationFilterは次のようになります。
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
// Correspond each "Authorize" role to an oauth2 scope, since I don't have any "Roles" defined, this didn't work
// and is in most of the Apply methods I found online. If you are like me and your [Authorize] tag doesn't contain
// any roles this will not work.
//var scopes = apiDescription.ActionDescriptor.GetFilterPipeline()
// .Select(filterInfo => filterInfo.Instance)
// .OfType<AuthorizeAttribute>()
// .SelectMany(attr => attr.Roles.Split(','))
// .Distinct();
var scopes = new List<string>() { "Read" }; // For me I just had one scope that is added to all all my methods, you might have to be more selective on how scopes are added.
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は次のようになります。
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "waPortal");
c.OAuth2("oauth2")
.Description("OAuth2 Client Credentials Grant Flow")
.Flow("application")
.TokenUrl("http://security.RogueOne.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: "swaggerUI",
clientSecret: "BigSecretWooH00",
realm: "swagger-realm",
appName: "Swagger UI"
);
});
}
最後の部分は理解するのが最も困難でした。これは、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.
ここでこのエラーについて説明しました Swagger UIが応答を解析していません 。これは、IdentityServer3が「Access-Control-Allow-Origin: 」の応答ヘッダーを正しく追加していないことが原因でした。 http:// localhost:62561 "クライアントの作成を次のように更新することで、IdentityServer3にそのヘッダーを送信させることができます。
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は私のパズルの最後のピースでした。うまくいけば、これは同じ問題に直面している他の誰かを助ける