2016-10-03 3 views
0

Ich versuche, Swagger (über Swashbuckle) auf meinem webApi einzurichten. Ich habe es auf den Punkt gebracht, dass es meine Methoden erfolgreich zeigt, und die offenen Methoden funktionieren gut.Swagger Aktivieren clientseitiger oAuth-Anmeldeinformationen

Die meisten Methoden auf meiner API verwenden oAuth2 zur Authentifizierung mit dem Erteilungsschlüssel client_credentials. Ich versuche, die Swagger-Benutzeroberfläche so einzurichten, dass der Benutzer seine Anmeldeinformationen in Textfelder eingeben und verwenden kann.

Dies ist, was ich bisher:

Swashbuckle Config

public static class SwashbuckleConfig 
{ 
    public static void Configure(HttpConfiguration config) 
    { 
     config.EnableSwagger(c => 
      { 
       c.SingleApiVersion("v1", "Configuration Api Config"); 
       c.OAuth2("oauth2") 
        .Description("OAuth2") 
        .Flow("application") 
        .TokenUrl("http://localhost:55236/oauth/token") 
        .Scopes(scopes => 
        { 
         scopes.Add("write", "Write Access to protected resources"); 
        }); 

       c.OperationFilter<AssignOAuth2SecurityRequirements>(); 
      }) 
      .EnableSwaggerUi(c => 
      { 
       c.EnableOAuth2Support("Test", "21", "Test.Documentation"); 
       c.InjectJavaScript(Assembly.GetAssembly(typeof(SwashbuckleConfig)), 
          "InternalAPI.Swagger.client-credentials.js"); 

      }); 
    } 

    public class AssignOAuth2SecurityRequirements : IOperationFilter 
    { 
     public void Apply(Operation operation, SchemaRegistry schemaRegistry, 
         ApiDescription apiDescription) 
     { 
      //All methods are secured by default, 
      //unless explicitly specifying an AllowAnonymous attribute. 
      var anonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(); 
      if (anonymous.Any()) return; 

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

      var requirements = new Dictionary<string, IEnumerable<string>> 
      { 
       { "oauth2", Enumerable.Empty<string>() } 
      }; 

      operation.security.Add(requirements); 
     } 
    } 
} 

Client-credentials.js

(function() { 
    $(function() { 
     var basicAuthUi = 
      '<div class="input">' + 
       '<label text="Client Id" /><input placeholder="clientId" id="input_clientId" name="Client Id" type="text" size="25">' + 
       '<label text="Client Secret" /><input placeholder="secret" id="input_secret" name="Client Secret" type="password" size="25">' + 
       '</div>'; 

     $(basicAuthUi).insertBefore('div.info_title'); 
     $("#input_apiKey").hide(); 

     $('#input_clientId').change(addAuthorization); 
     $('#input_secret').change(addAuthorization); 
    }); 

    function addAuthorization() { 
     var username = $('#input_clientId').val(); 
     var password = $('#input_secret').val(); 

     if (username && username.trim() !== "" && password && password.trim() !== "") { 

      //What do I need to do here?? 
      //var basicAuth = new SwaggerClient.oauth2AUthorisation(username, password); 
      //window.swaggerUi.api.clientAuthorizations.add("oauth2", basicAuth); 

      console.log("Authorization added: ClientId = " 
       + username + ", Secret = " + password); 
     } 
    } 
})(); 

Die clientseitige Beispiel ich versuchte, Modifizieren war von here. Offensichtlich ist dies für die Standard-Authentifizierung, aber ich muss es für oAuth anpassen.

Was muss ich tun, damit vor dem Aufruf der Api-Methode ein Token generiert wird?

+0

Ich denke, das ist, was Sie betrachten: http://stackoverflow.com/questions/39729188/im-not-getting-a-scope-checkbox-when-the-authorize-tag-doesnt -contain-roles-a/39750143 # 39750143 –

Antwort

0

Zuerst möchte ich sagen, dass Sie Client-Anmeldeinformationen nicht von Client-Seite fließen müssen; Aber immer noch habe ich diese Regel heute gebrochen:). Nun, bis es vom Benutzer eingegeben wird, sollte es in Ordnung sein (ich hoffe, Sie verwenden TLS).

Normalerweise würden Sie impliziten Typen implementieren hier können Sie sich hier auf überprüfen, wie man (ich persönlich habe es nicht versucht): https://danielwertheim.se/use-identityserver-in-swaggerui-to-consume-a-secured-asp-net-webapi/

So todo, dass Sie diese Sicherheitsdefinition müssen entfernen: c.OperationFilter() ; können Sie den Rest verlassen.

und fügen Sie einfach diesen Code:

function addApiKeyAuthorization() { 

      var clientId = $('#input_clientid')[0].value; 
      var clientSecret = $('#input_clientsecret')[0].value; 

      if (clientId == '' || clientSecret == "") 
       return; 

      var token = getToken(clientId, clientSecret, 'a defined scope'); 

      var authKeyHeader = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + token.access_token, "header"); 
      console.log("authKeyHeader", authKeyHeader); 
      window.swaggerUi.api.clientAuthorizations.add("Authorization", authKeyHeader); 

      //handle token expiration here 
     } 

     function getToken(clientId, clientSecret, scope) { 

      var authorizationUrl = '<url to token service>/connect/token'; 
      var authorizationParams = "grant_type=client_credentials&scope=" + scope; 
      var basicAuth = window.btoa(clientId + ":" + clientSecret) 
      var token = ""; 

      $.ajax({ 
       type: 'POST', 
       url: authorizationUrl, 
       contenttype: 'x-www-form-urlencoded', 
       headers: { 
        'Authorization': 'basic ' + basicAuth 
       }, 
       data: authorizationParams, 
       success: function (data) { 
        token = data; 
       }, 
       error: function (data) { 
        // don't worry about it, swagger will respond that something went wrong :) 
       }, 
       async: false 
      }); 

      return token; 
      //example response format: {access_token: "86f2bc88dcd1e6919ef0dadbde726c52", expires_in: 3600, token_type: "Bearer"} 
     } 

     $('#explore').on('click', addApiKeyAuthorization); 

Ich hoffe, das hilft. Viel Spaß:)

Verwandte Themen