You can do this without drivers.
You can achieve it using an area light instead of a spot light, then make use of the Geometry node's Normal and Incoming socket and subtract them using a Vector Math node.
It still suffers from tiling/mirroring artifacts at extreme angles like the solutions by @gandalf3, but those can be adjusted with the Vector Mapping node as long as multiple instances of the light are maintain within a certain angle threshold from eachother, and overall it seems like a more maintainable solution in the long term.
Blender 2.79+
As of Blender 2.79 Blender, Cycles can correctly use lamp texture coordinates directly for Spot, Area, and Point lamp types without any further contrivances.
Committed by Lukas Stockner Cycles: Implement texture coordinates for Point, Spot and Area Lamps
Cycles: Implement texture coordinates for Point, Spot and Area Lamps
When using the Normal output of the Texture Coordinate node on Point and Spot lamps, the coordinates now depend on the rotation of the lamp. On Area lamps, the Parametric output of the Geometry node now returns UV coordinates on the area lamp.
Credit for the Area lamp part goes to Stefan Werner (from D1995).
Just use the Normal output on the Texture Coordinates node as vector input for a texture.
If you are using an image based texture you may need to offset the texture coordinates by $0.5$ units on $X$ and $Y$ axis using a Vector Mapping node to center the image on the projection direction.
Smaller sized area lights will produce sharper image projections.