Fill a bowl with alphabet soup

05AB1E, 20 18 16 15 14 bytes

*j.rS²ô2Føε8.ø

Takes three inputs in the order: height, width, string. Output as a 2D list of characters.
Uses 8 as border, but could be any digit.

-1 byte thanks to @Grimy.

Try it online or verify all test cases. (TIO contains }}J» in the footer to pretty-print the result; feel free to remove it to see the actual output 2D list of characters instead.)

Explanation:

*               # Multiply the (implicit) width and height inputs
 j              # Pad the (implicit) input-string with up to that amount of leading spaces,
                # so the total string-length is equal to that value
  .r            # Shuffle the characters in the string
    S           # Convert the string to a list of characters
                # (edge-case for the zip below with strings of size 1 with 1x1 dimensions)
     ²          # Push the width input again
      ô         # Split the list of characters into parts of that size
       2F       # Loop 2 times:
         ø      #  Zip/transpose the 2D list; swapping rows/columns
          ε     #  Inner map over each line:
           8.ø  #   And surround this line-list with a leading/trailing "8"
                # (after the loop, the result is output implicitly)

APL (Dyalog Unicode), 25 bytesSBCS

'#',∘⌽∘⍉⍣4{⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}

Try it online!

-22 thanks to @ngn, -7 thanks to @ngn and @Adám

Explanation:

'#',∘⌽∘⍉⍣4{⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}
          {            ⍵} ⍝ Function that generates the content
                          ⍝  argument: ⍵ (width and height), ⍺ (string)
                     ×/   ⍝ get the product
                   ?⍨     ⍝ For each randomized elements
               ↓∘⍺¨       ⍝ take the character in ⍺
           ⍵⍴⊃¨           ⍝ turn it back into a matrix of shape ⍵
    ∘ ∘ ⍣4                ⍝ Then, 4 times, do these 3 things:
'#',                      ⍝ - prepend a # to the axis
     ⌽                    ⍝ - reverse the columns
       ⍉                  ⍝ - swap columns and lines

APL (Dyalog Extended), 21 bytesSBCS

The rim's angles are different characters

{⌂disp⊂⍵⍴⊃¨↓∘⍺¨?⍨×/⍵}

Try it online!

Using the dfn to display the box.


Python 3, 110 bytes

lambda s,m,n,r=['#']:[r+(n*r+[i for i,j in{*zip(s+m*n*' ',range(m*n))}]+n*r)[k*n:-~k*n]+r for k in range(m+2)]

Try it online!

Randomizes by using a set comprehension and returns a 2D character array.