[erlang-questions] Declarative Security in Erlang
Tim Watson
watson.timothy@REDACTED
Mon May 21 21:59:57 CEST 2012
On 21/05/2012 20:43, Andrew Berman wrote:
> Does anyone have any thoughts on this? I was thinking about just
> starting a new process every time I access the API and then store the
> current user in there. Any thoughts?
>
There are lots of ways to do this, so I guess it just depends. Passing
the user about in your various functions might seem bothersome, but it
is 'pure' - and that has merit. If you're holding on to a user in either
a request or session like object, then putting the security context
information into the request/session data structure seems like a
perfectly sane approach to me. Even though in J2SE you'd make a static
call such as SecurityContextHolder.getCurrentUser you can still find
this information tucked away in context data, for example, in web apps
and the like.
Interestingly enough, those static calls are often resolved under the
covers but reading a thread local variable, so having a process per
activity/request and pushing the user data into the process dictionary
might not be the wrong thing to do after all. Just bare in mind that you
can't make *safe* use of this unless you're absolutely certain whichever
code executes get_current_user is definitely running in the same process.
So you have two choices here really:
around_advice(#annotation{data={mode, pdict}}, M, F, Inputs) ->
case get(current_user) of
undefined->
handle_restricted(M, F, Inputs);
#user{}->
annotation:call_advised(M, F, Inputs)
end.
Or you could you ets/mnesia/gen_server or whatever instead of the
process dictionary - these are *safer* in that they're less likely to
surprise you if accessed from some 'other' process than the one you
expected. Another approach would be to store the index (1 bound) of the
user record in the argument set for the annotation, like so:
around_advice(#annotation{data={user_record_idx, Idx}}, M, F, Inputs) ->
User = lists:nth(Idx, Inputs), case check(User) of
restricted->
handle_restricted(M, F, Inputs);
ok->
annotation:call_advised(M, F, Inputs)
end.
Of course you don't have to use 'around_advice' - if you just need
'before_advice' to prevent unauthorised access, then that will work fine
too. HTH - and don't forgot to submit any issues/bugs you come across! :)
Cheers,
Tim
> Thanks again!
>
> On Sat, May 19, 2012 at 12:38 PM, Andrew Berman <rexxe98@REDACTED
> <mailto:rexxe98@REDACTED>> wrote:
>
> Hey all,
>
> I'm trying to mimic (as much as I can) what JEE 6 does with
> security on domain objects. Essentially what I'd like to do is
> create an annotation using Tim's awesome annotation code
> (https://github.com/hyperthunk/annotations) and test on a user's
> roles. The one issue I'm wrestling with is how to get the user
> into the annotation. The obvious way is to have every function I
> put the annotation on take in a user record and then loop through
> the arguments of the function looking for the user record. That
> way doesn't seem very elegant to me, though. I really want to
> just say something like User = get_current_user(...). Has anyone
> tackled this sort of issue or have any advice on how to handle it
> in an Erlang safe manner?
>
> Thanks,
>
> Andrew
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120521/13b2d130/attachment.htm>
More information about the erlang-questions
mailing list