【问题标题】:Swagger Enabling Client-Side oAuth CredentialsSwagger 启用客户端 oAuth 凭据
【发布时间】:2017-03-27 01:10:17
【问题描述】:

我正在尝试在我的 webApi 上设置 Swagger(通过 Swashbuckle)。我已经成功地展示了我的方法,并且开放的方法工作正常。

我的 Api 上的大多数方法都使用 oAuth2 进行身份验证,使用 client_credentials 授权类型。我正在尝试设置 Swagger UI,以便用户可以将他们的凭据输入到文本框中,并让它使用它。

这是我目前所拥有的:

Swashbuckle 配置

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

我试图修改的客户端示例来自here。显然这是用于基本身份验证,但我需要对其进行修改以适应 oAuth。

在调用 Api 方法之前,我需要做什么才能使其生成令牌?

【问题讨论】:

标签: c# oauth swagger


【解决方案1】:

首先我想说的是,您不得使用来自客户端的客户端凭据流; 但我今天也打破了这条规则:)。好吧,直到用户输入它应该没问题(我希望你使用的是 TLS)。

通常你会在这里实现隐式类型,你可以在这里查看如何(我个人没有尝试过):https://danielwertheim.se/use-identityserver-in-swaggerui-to-consume-a-secured-asp-net-webapi/

所以你需要删除这个安全定义: 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);

我希望这会有所帮助。玩得开心:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2019-12-03
    • 2014-05-04
    相关资源
    最近更新 更多