What's the difference between EXECUTE AS USER and EXECUTE AS LOGIN that makes the second one behave unexpectedly?
A member of sysadmin group is always mapped to dbo, even if it has an explicit user in the database. So it looks like the login WEB is member of sysadmin, hence USER_NAME() correctly returns dbo in the second case.