The AuthorizeAttribute doesn't effect authorization using JWT in dotnet core webapi 2.1 application












0















I'm trying to use JWT in a core webapi application. Here is my Startup.ConfigureServices():



services.AddDbContextPool("Bla Bla");
services.AddIdentity<IdentityUser, IdentityRole>("Bla Bla");

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(o => {
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(c => {
c.RequireHttpsMetadata = false;
c.SaveToken = true;
c.TokenValidationParameters =
new TokenValidationParameters {
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero
};
});

services.AddRouting("Bla Bla");
services.AddMvcCore("Bla Bla").AddControllersAsServices();


And this is Startup.Configure() method:



app.UseAuthentication();
app.UseMvc(rb =>
{ rb.MapRoute("api_default", "{controller}/{action}/{id?}"); });


Anyway, I have created a protect action to test (which I'm expecting to return an HTTP 401 Unauthorized error):



public class AccountController : ControllerBase {
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return "Authorized!";
}
}


But its getting authorized and responsing "Authorized!" all the time. It seems the Authorize attribute doesn't effect at all. Am I missing something?



P.S. I have tried both [Authorize] and [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] attribute.



P.S.2 I have tried extending the controller from both ControllerBase and Controller.



P.S.3 I have tried without clearing default claims (removed this line JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();).



None of them worked.



Framework and packages info:




  • Target Framework: netcoreapp2.1


  • Microsoft.AspNetCore Version = 2.1.6


  • Microsoft.AspNetCore.Authentication.JwtBearer Version = 2.1.2


  • Microsoft.AspNetCore.Identity.EntityFrameworkCore Version = 2.1.6


  • Microsoft.AspNetCore.Mvc.Core Version = 2.1.3


UPDATE:



According to @sellotape's comment, I have returned the User object from the action:



[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return User;
}


And here is the output JSON:



{
"identities": [
{
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
],
"identity": {
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"claims":
}









share|improve this question

























  • Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

    – sellotape
    Nov 25 '18 at 8:39











  • @sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

    – javad amiry
    Nov 25 '18 at 9:13











  • I think you're missing services.AddAuthorization(); in ConfigureServices()...

    – sellotape
    Nov 25 '18 at 9:23











  • @sellotape I added services.AddAuthorization() but nothing changed ):

    – javad amiry
    Nov 25 '18 at 9:39






  • 1





    thanks; I've added an answer now.

    – sellotape
    Nov 25 '18 at 12:19
















0















I'm trying to use JWT in a core webapi application. Here is my Startup.ConfigureServices():



services.AddDbContextPool("Bla Bla");
services.AddIdentity<IdentityUser, IdentityRole>("Bla Bla");

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(o => {
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(c => {
c.RequireHttpsMetadata = false;
c.SaveToken = true;
c.TokenValidationParameters =
new TokenValidationParameters {
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero
};
});

services.AddRouting("Bla Bla");
services.AddMvcCore("Bla Bla").AddControllersAsServices();


And this is Startup.Configure() method:



app.UseAuthentication();
app.UseMvc(rb =>
{ rb.MapRoute("api_default", "{controller}/{action}/{id?}"); });


Anyway, I have created a protect action to test (which I'm expecting to return an HTTP 401 Unauthorized error):



public class AccountController : ControllerBase {
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return "Authorized!";
}
}


But its getting authorized and responsing "Authorized!" all the time. It seems the Authorize attribute doesn't effect at all. Am I missing something?



P.S. I have tried both [Authorize] and [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] attribute.



P.S.2 I have tried extending the controller from both ControllerBase and Controller.



P.S.3 I have tried without clearing default claims (removed this line JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();).



None of them worked.



Framework and packages info:




  • Target Framework: netcoreapp2.1


  • Microsoft.AspNetCore Version = 2.1.6


  • Microsoft.AspNetCore.Authentication.JwtBearer Version = 2.1.2


  • Microsoft.AspNetCore.Identity.EntityFrameworkCore Version = 2.1.6


  • Microsoft.AspNetCore.Mvc.Core Version = 2.1.3


UPDATE:



According to @sellotape's comment, I have returned the User object from the action:



[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return User;
}


And here is the output JSON:



{
"identities": [
{
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
],
"identity": {
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"claims":
}









share|improve this question

























  • Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

    – sellotape
    Nov 25 '18 at 8:39











  • @sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

    – javad amiry
    Nov 25 '18 at 9:13











  • I think you're missing services.AddAuthorization(); in ConfigureServices()...

    – sellotape
    Nov 25 '18 at 9:23











  • @sellotape I added services.AddAuthorization() but nothing changed ):

    – javad amiry
    Nov 25 '18 at 9:39






  • 1





    thanks; I've added an answer now.

    – sellotape
    Nov 25 '18 at 12:19














0












0








0


1






I'm trying to use JWT in a core webapi application. Here is my Startup.ConfigureServices():



services.AddDbContextPool("Bla Bla");
services.AddIdentity<IdentityUser, IdentityRole>("Bla Bla");

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(o => {
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(c => {
c.RequireHttpsMetadata = false;
c.SaveToken = true;
c.TokenValidationParameters =
new TokenValidationParameters {
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero
};
});

services.AddRouting("Bla Bla");
services.AddMvcCore("Bla Bla").AddControllersAsServices();


And this is Startup.Configure() method:



app.UseAuthentication();
app.UseMvc(rb =>
{ rb.MapRoute("api_default", "{controller}/{action}/{id?}"); });


Anyway, I have created a protect action to test (which I'm expecting to return an HTTP 401 Unauthorized error):



public class AccountController : ControllerBase {
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return "Authorized!";
}
}


But its getting authorized and responsing "Authorized!" all the time. It seems the Authorize attribute doesn't effect at all. Am I missing something?



P.S. I have tried both [Authorize] and [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] attribute.



P.S.2 I have tried extending the controller from both ControllerBase and Controller.



P.S.3 I have tried without clearing default claims (removed this line JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();).



None of them worked.



Framework and packages info:




  • Target Framework: netcoreapp2.1


  • Microsoft.AspNetCore Version = 2.1.6


  • Microsoft.AspNetCore.Authentication.JwtBearer Version = 2.1.2


  • Microsoft.AspNetCore.Identity.EntityFrameworkCore Version = 2.1.6


  • Microsoft.AspNetCore.Mvc.Core Version = 2.1.3


UPDATE:



According to @sellotape's comment, I have returned the User object from the action:



[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return User;
}


And here is the output JSON:



{
"identities": [
{
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
],
"identity": {
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"claims":
}









share|improve this question
















I'm trying to use JWT in a core webapi application. Here is my Startup.ConfigureServices():



services.AddDbContextPool("Bla Bla");
services.AddIdentity<IdentityUser, IdentityRole>("Bla Bla");

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(o => {
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(c => {
c.RequireHttpsMetadata = false;
c.SaveToken = true;
c.TokenValidationParameters =
new TokenValidationParameters {
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
ClockSkew = TimeSpan.Zero
};
});

services.AddRouting("Bla Bla");
services.AddMvcCore("Bla Bla").AddControllersAsServices();


And this is Startup.Configure() method:



app.UseAuthentication();
app.UseMvc(rb =>
{ rb.MapRoute("api_default", "{controller}/{action}/{id?}"); });


Anyway, I have created a protect action to test (which I'm expecting to return an HTTP 401 Unauthorized error):



public class AccountController : ControllerBase {
[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return "Authorized!";
}
}


But its getting authorized and responsing "Authorized!" all the time. It seems the Authorize attribute doesn't effect at all. Am I missing something?



P.S. I have tried both [Authorize] and [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] attribute.



P.S.2 I have tried extending the controller from both ControllerBase and Controller.



P.S.3 I have tried without clearing default claims (removed this line JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();).



None of them worked.



Framework and packages info:




  • Target Framework: netcoreapp2.1


  • Microsoft.AspNetCore Version = 2.1.6


  • Microsoft.AspNetCore.Authentication.JwtBearer Version = 2.1.2


  • Microsoft.AspNetCore.Identity.EntityFrameworkCore Version = 2.1.6


  • Microsoft.AspNetCore.Mvc.Core Version = 2.1.3


UPDATE:



According to @sellotape's comment, I have returned the User object from the action:



[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public async Task<object> Info() {
return User;
}


And here is the output JSON:



{
"identities": [
{
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
}
],
"identity": {
"isAuthenticated": false,
"claims": ,
"roleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"claims":
}






c# authorization jwt asp.net-core-webapi netcoreapp2.1






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 9:12







javad amiry

















asked Nov 25 '18 at 8:29









javad amiryjavad amiry

15.3k84799




15.3k84799













  • Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

    – sellotape
    Nov 25 '18 at 8:39











  • @sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

    – javad amiry
    Nov 25 '18 at 9:13











  • I think you're missing services.AddAuthorization(); in ConfigureServices()...

    – sellotape
    Nov 25 '18 at 9:23











  • @sellotape I added services.AddAuthorization() but nothing changed ):

    – javad amiry
    Nov 25 '18 at 9:39






  • 1





    thanks; I've added an answer now.

    – sellotape
    Nov 25 '18 at 12:19



















  • Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

    – sellotape
    Nov 25 '18 at 8:39











  • @sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

    – javad amiry
    Nov 25 '18 at 9:13











  • I think you're missing services.AddAuthorization(); in ConfigureServices()...

    – sellotape
    Nov 25 '18 at 9:23











  • @sellotape I added services.AddAuthorization() but nothing changed ):

    – javad amiry
    Nov 25 '18 at 9:39






  • 1





    thanks; I've added an answer now.

    – sellotape
    Nov 25 '18 at 12:19

















Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

– sellotape
Nov 25 '18 at 8:39





Put a breakpoint in that controller action and examine the user claims and identities to see where the authenticated Identity is coming from. That should give some clues...

– sellotape
Nov 25 '18 at 8:39













@sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

– javad amiry
Nov 25 '18 at 9:13





@sellotape nothing important came out. Claims and identities are empty. See the update to see the complete User object.

– javad amiry
Nov 25 '18 at 9:13













I think you're missing services.AddAuthorization(); in ConfigureServices()...

– sellotape
Nov 25 '18 at 9:23





I think you're missing services.AddAuthorization(); in ConfigureServices()...

– sellotape
Nov 25 '18 at 9:23













@sellotape I added services.AddAuthorization() but nothing changed ):

– javad amiry
Nov 25 '18 at 9:39





@sellotape I added services.AddAuthorization() but nothing changed ):

– javad amiry
Nov 25 '18 at 9:39




1




1





thanks; I've added an answer now.

– sellotape
Nov 25 '18 at 12:19





thanks; I've added an answer now.

– sellotape
Nov 25 '18 at 12:19












1 Answer
1






active

oldest

votes


















1














The main issue is that when you use .AddMvcCore(), you're only wiring up a small part of what you get when you use .AddMvc() instead. For many solutions, it's simpler to just use the latter, as you then automatically get the following added and ready to use [source]:




  • API Explorer

  • Authorization

  • Views

  • Razor View Engine

  • Razor Pages

  • JSON Formatters

  • CORS

  • (a few others)


If you prefer to only add what you absolutely need, you can elect to use .AddMvcCore() instead, but then you need to explicitly add the MVC services you require; e.g. in this case (Authorization), you would need to



services.AddMvcCore()
.AddAuthorization();


Note how .AddAuthorization() here is being applied to the result of services.AddMvcCore(), which is an IMvcBuilder, not to services, which is an IServiceCollection.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465832%2fthe-authorizeattribute-doesnt-effect-authorization-using-jwt-in-dotnet-core-web%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    The main issue is that when you use .AddMvcCore(), you're only wiring up a small part of what you get when you use .AddMvc() instead. For many solutions, it's simpler to just use the latter, as you then automatically get the following added and ready to use [source]:




    • API Explorer

    • Authorization

    • Views

    • Razor View Engine

    • Razor Pages

    • JSON Formatters

    • CORS

    • (a few others)


    If you prefer to only add what you absolutely need, you can elect to use .AddMvcCore() instead, but then you need to explicitly add the MVC services you require; e.g. in this case (Authorization), you would need to



    services.AddMvcCore()
    .AddAuthorization();


    Note how .AddAuthorization() here is being applied to the result of services.AddMvcCore(), which is an IMvcBuilder, not to services, which is an IServiceCollection.






    share|improve this answer




























      1














      The main issue is that when you use .AddMvcCore(), you're only wiring up a small part of what you get when you use .AddMvc() instead. For many solutions, it's simpler to just use the latter, as you then automatically get the following added and ready to use [source]:




      • API Explorer

      • Authorization

      • Views

      • Razor View Engine

      • Razor Pages

      • JSON Formatters

      • CORS

      • (a few others)


      If you prefer to only add what you absolutely need, you can elect to use .AddMvcCore() instead, but then you need to explicitly add the MVC services you require; e.g. in this case (Authorization), you would need to



      services.AddMvcCore()
      .AddAuthorization();


      Note how .AddAuthorization() here is being applied to the result of services.AddMvcCore(), which is an IMvcBuilder, not to services, which is an IServiceCollection.






      share|improve this answer


























        1












        1








        1







        The main issue is that when you use .AddMvcCore(), you're only wiring up a small part of what you get when you use .AddMvc() instead. For many solutions, it's simpler to just use the latter, as you then automatically get the following added and ready to use [source]:




        • API Explorer

        • Authorization

        • Views

        • Razor View Engine

        • Razor Pages

        • JSON Formatters

        • CORS

        • (a few others)


        If you prefer to only add what you absolutely need, you can elect to use .AddMvcCore() instead, but then you need to explicitly add the MVC services you require; e.g. in this case (Authorization), you would need to



        services.AddMvcCore()
        .AddAuthorization();


        Note how .AddAuthorization() here is being applied to the result of services.AddMvcCore(), which is an IMvcBuilder, not to services, which is an IServiceCollection.






        share|improve this answer













        The main issue is that when you use .AddMvcCore(), you're only wiring up a small part of what you get when you use .AddMvc() instead. For many solutions, it's simpler to just use the latter, as you then automatically get the following added and ready to use [source]:




        • API Explorer

        • Authorization

        • Views

        • Razor View Engine

        • Razor Pages

        • JSON Formatters

        • CORS

        • (a few others)


        If you prefer to only add what you absolutely need, you can elect to use .AddMvcCore() instead, but then you need to explicitly add the MVC services you require; e.g. in this case (Authorization), you would need to



        services.AddMvcCore()
        .AddAuthorization();


        Note how .AddAuthorization() here is being applied to the result of services.AddMvcCore(), which is an IMvcBuilder, not to services, which is an IServiceCollection.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 12:18









        sellotapesellotape

        5,73821619




        5,73821619
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465832%2fthe-authorizeattribute-doesnt-effect-authorization-using-jwt-in-dotnet-core-web%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga