2015-11-17 26 views
9

Im IdentityServer3を使用して、クライアントクレデンシャルでWeb APIを保護します。 Swashbuckleを使用していますが、SwaggerConfigでクライアント証明書(アプリケーション)フローのOauth2を有効にする方法を理解できません。どんな助けもありがとう!SwashbuckleでOauth2クライアントの資格情報フローを有効にする

+0

あなたはこれに対する解決策を見つけましたか? –

+0

いいえ、申し訳ありません。私たちはこれを私たちのために解決した生産でスワッガーを使用しないことに決めました。 – mstrand

答えて

7

私はこれを得ることができました。答えのほとんどはhereです。

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"); 
    }); 

ここでの重要な変更は、私はまた、これはあなたの特定の認可スキームが設定されているにだけ依存している代わりに.AuthorizationUrl.TokenUrlコールを使用.Flow("application")です。

私はまた、これは、表示するために認証スイッチを取得するのに十分であるべきで

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); 
    } 
} 

をわずかに異なるAssignOAuth2SecurityRequirementsクラスを使用していました。私のもう一つの問題は、デフォルトの認証ダイアログが設定されているため、ユーザーはスコープを選択してから[承認]をクリックするだけで済みます。私の場合は、認証が設定されているためにこれが機能しませんでした。 swagger-oauth.jsスクリプトにダイアログを書き直してSwaggerUIに挿入する必要がありました。

+0

スワッガー文書の消費者がclient_idまたはclient_idとsecret_keyを提供できるようにする方法はありますか? – Zoop

+0

確かに、それがあなたの認証方法です。 "grant_type:client_credentials"、 "client_id:<クライアントID>"、 "secret_key:<秘密鍵>"というログインフォームのPOSTリクエストを作成し、それをトークンurlに投稿してください。次に、OAuthAuthorizationServerProviderをサブクラス化してログインを処理します。 –

+0

私はより具体的にすべきだった...私はポップアップフォームを介して意味。 – Zoop

2

この問題を解決するにはもう少し問題がありましたが、多くの忍耐力を持ってSwaggerUIにJavaScriptを注入しなくても機能するソリューションが見つかりました。注:私の困難の一部は、偉大な製品であるIdentityServer3を使用していたことが原因であった可能性があります。

私の変更の多くは上記の請求書の回答に似ていますが、私の操作フィルタは異なります。私のコントローラ内のすべてのメソッドがそうのような無役割と承認のタグを持っている:

[Authorize] 
// Not this 
[Authorize(Roles = "Read")] // This doesn't work for me. 

承認に定義されていない役割を持つ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" 
      ); 
     }); 
} 

最後の部分は私が最終的にネットワークのタグの上の小さな赤いXを示したChromeデベロッパーツールの助けを借りてやっている、把握する最も困難でした「:http://localhost:62561アクセス制御 - 許可 - 起源」あなたはそのヘッダを送信するためにIdentityServer3を強制することができ、私は正しくのレスポンスヘッダを追加していないここに起因するIdentityServer3にしたSwagger UI not parsing reponseこのエラーを説明

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. 

:次のエラーメッセージをhowingクライアントの作成を次のように更新してください。

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は私のパズルの最後の部分でした。うまくいけば、これは同じ問題に直面している他の誰かの助けになるでしょう

関連する問題