I would use a view. You've also missed out an option - a table-valued function.
There are 3 possibilities here - a view, a table-valued function, or a stored procedure.
A view is basic - it cannot be parameterised. But it can easily be composed as part of a larger query and the optimizer can (usually) be expected to produce as optimal a plan as if you had included the body of the view in your query (indeed, it's often liked to a macro which "expands out" into your query).
A table-valued function may be parameterised, but cannot produce any side effects in the database. However, it can still be composed into queries, and (if it's an inline TVF, and you have a tail wind) the optimizer can still, hopefully, produce an optimal plan.
A stored procedure is all powerful - it can do anything, it can make changes to the database, it can compute results however it needs to. However, your only option is to execute it. It's execution takes place within a separate scope, and it cannot be composed into a larger query.
So I'd recommend using the least powerful of the above that meets your needs - because it provides the most scope for being able to reuse it as part of other queries later.
Re: Performance - if you're just doing a plain SELECT *
against a view or are just executing a stored procedure, there shouldn't be any noticeable difference.
Re: Security - again, not much difference - you can as easily GRANT
/DENY
SELECT
on a view as you can EXEC
on a stored procedure.