2016-10-03 3 views
0

Я пытаюсь настроить Swagger (через Swashbuckle) на мой webApi. Я догадался, что он успешно показывает мои методы, и открытые методы работают нормально.Swagger Включение учетных данных oAuth на стороне клиента

Большинство методов на моем Api используют oAuth2 для аутентификации, используя тип субсидии client_credentials. Я пытаюсь настроить пользовательский интерфейс Swagger, чтобы пользователь мог ввести свои учетные данные в текстовые поля и использовать его.

Это то, что я до сих пор:

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

клиент-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); 
     } 
    } 
})(); 

стороне клиента пример, который я пытался изменение было от here. Очевидно, что это обычная проверка подлинности, но мне нужно изменить ее в соответствии с требованиями OAuth.

Что нужно сделать, чтобы заставить его генерировать токен перед вызовом метода Api?

+0

Я думаю, что это то, что вы смотрите: http://stackoverflow.com/questions/39729188/im-not-getting-a-scope-checkbox-when-the-authorize-tag-doesnt -contain-роль-а/39750143 # 39750143 –

ответ

0

Прежде всего, я хочу сказать, что вы НЕ ДОЛЖНЫ использовать поток учетных данных клиента с клиентской стороны; Но все же я тоже нарушил это правило сегодня:). Ну, пока он не будет введен пользователем, все должно быть хорошо (надеюсь, вы используете TLS).

Обычно вы бы реализовать неявный тип здесь вы можете проверить здесь о том, как (лично я не пробовал): https://danielwertheim.se/use-identityserver-in-swaggerui-to-consume-a-secured-asp-net-webapi/

Так TODO, что вам нужно будет удалить это определение безопасности: c.OperationFilter() ; вы можете оставить все остальное.

и просто добавить этот код:

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

Я надеюсь, что это помогает. Удачи!)

Смежные вопросы