[erlang-questions] Declarative Security in Erlang

Tim Watson <>
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 < 
> <mailto:>> 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
> 
> 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.html>


More information about the erlang-questions mailing list