I guess you can achieve this by setting the user's login shell to something very restricted, e.g. something like "Sleep Dummy Shell". Quoting it's website,
This is a simple do-nothing, sleep-forever program that can be used as a login shell (in Linux or Unix) to keep the connection open but without interactive shell. We use it to create SSH accounts for users who will only use them for SSH-tunneling; to create an encrypted tunnel to our servers [...]
Most restricted shells still allow execution of local commands from the SSH account. Setting the account shell to something like
/bin/false (or any other simple programs) usually won't work because the tunnel is closed as soon as the program finish its execution. Sleep Dummy Shell just sleeps until its execution is terminated by the user or the tunnel is closed.
You get the idea, a simple program does a part the trick,
sleepshell.c has ~20 lines of C.
I'm not sure if this already is secure enough, i.e. what this means for using
ssh <server> /bin/bash or similar, for example.
See this answer (by michael-n) for more hints and information.