Custom permalink accept any params

This is, I suppose, just how the query parser works. If you create a new WP_Query instance, and provide a post name, any taxonomy parameters you add will be ignored and will not be added to the query. Post uniqueness is determined entirely based on post slug, and uniqueness of slug is enforced.

It’s possible to fix, but I don’t really think it’s necessary. How would these random incorrect URLs be generated? If you visit one of these false URLs, you’ll see that the canonical link is the correct one, so search engines would not index these bad URLs, if they were somehow encountered.

So, that said, here’s a fix. Hook a function to wp, which is after the query is run, but before the template is loaded. Here we can check if it’s a singular post, get the ID of queried post, and check if it actually has these terms. If it doesn’t, we generate a 404.

function wpd_check_singular_post_terms() {
    global $wp_query;
    if( is_singular( 'post' )
    && isset( $wp_query->query_vars['location'] )
    && isset( $wp_query->query_vars['category_name'] ) ) {
        if( ! has_term( $wp_query->query_vars['location'], 'location', get_queried_object_id() )
        || ! has_term( $wp_query->query_vars['category_name'], 'category', get_queried_object_id() ) ){
            $wp_query->set_404();
            status_header( 404 );
        }
    }
}
add_action( 'wp', 'wpd_check_singular_post_terms' );

Note that the result is now not actually a 404! Surprise! Setting a 404 makes the redirect_guess_404_permalink function kick in, which gets the correct permalink for the requested post name, and 301 redirects there.