[ 
https://issues.apache.org/jira/browse/THRIFT-3979?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15677082#comment-15677082
 ] 

James E. King, III commented on THRIFT-3979:
--------------------------------------------

Some issues I have with this would be that you have to send the credentials 
with every request, which implies they need to be checked with every request, 
and represents putting secure information into more places in memory on 
multiple machines or on the wire more than necessary.  In one project I work 
on, the first argument to every API request is a map of credential information 
(just a token, not a username and password), which is less than ideal and I 
would LOVE to eliminate it.  I'd like to propose an alternative solution that 
would meet your use cases and be more secure, and simplify thrift interfaces.  

To date, thrift has always behaved session-less, i.e. there's no way to 
correlate information between two API calls and know they are from the same 
"client".  This is quite limiting in terms of interface design.  I implemented 
this solution in THRIFT-66 a long time ago in C# as part of a project I was 
working on.  I'll explain it in context of the existing C++ runtime:

Each connected client has an instantiated class, "TConnectedClient" which 
represents a connection, in today's runtime.

It would be possible to expose this to handler method implementations, or at 
least a thinner interface that would allow it to store something on behalf of, 
or retrieve something on behalf of the handler code.  We would be careful not 
to require an API change in how you define a method today.  I would suggest 
that in the C++ library at least we would use thread local storage to associate 
the thread with the TConnectedClient it is processing for, and then inside one 
of your implementations of a thrift method you could call something in the C++ 
runtime that would give you access to add, query, remove opaque information 
(opaque from the perspective of the thrift runtime, but it means something to 
you...)

Here's an example:

# You define a MultiplexedProtocol, where one service is called the "auth" 
service with an "authenticate" method and another service is called the "file" 
service and it defines a "delete" method.
# When your client connects, it sends authentication credentials to the "auth" 
service "authenticate" method that you write the implementation for.
# If authentication is successful in your implementation, your implementation 
creates a class (that you write) called AuthenticatedUser which contains 
username, userid, and permissions.
# Your implementation asks the thrift runtime to store an AuthenticatedUser* 
through an interface, and associate it with a key.  For example: {{ 
apache::thrift::ConnectedClient()->store("authdata", pAuthUser); }}
# Thrift tucks this away in the TConnectedClient for that connection.
# Your authenticate implementation returns "ok".
# The client now calls file::delete.  It doesn't need to provide credentials.  
What it does is ask for the pointer {{ 
apache::thrift::ConnectedClient()->retrieve("authdata") }} which either returns 
NULL indicating it isn't there, or it returns a valid pointer.  Now the 
file::delete call can access the user information that was authenticated in a 
previous call.

Of course we would need to make sure these things are self contained so 
TConnectedClient can delete them properly.  We don't want any pointer leaks 
here. :)

Now this works for connection based protocols like sockets.  It may not work at 
all for sessionless protocols unless someone adds something to the current 
implementations to allow them to associate clients with connections.  Or maybe 
we say it doesn't make sense to support this with sessionless protocols... not 
sure.

So this would achieve what you requested, but not put the burden on the client 
to remember and re-send authentication with every request.  It could be used 
for other things, but I would expect it to be used primarily for 
authentication.  I certainly would use it this way in multiple projects.  It 
also does not require any changes to protocols.

> offer TExtendedBinaryProtocol for customers
> -------------------------------------------
>
>                 Key: THRIFT-3979
>                 URL: https://issues.apache.org/jira/browse/THRIFT-3979
>             Project: Thrift
>          Issue Type: Story
>          Components: C++ - Library, Java - Library
>    Affects Versions: 0.9.3
>            Reporter: Xiaoshuang LU
>
> Sometimes, customers wanna put some options (username, password, id, etc.) in 
> each request and response. And these options ought to be transparent for 
> applications.
> Unfortunately, thrift protocol does not have good extensibility for extra 
> functionalities. I would like to propose the following solution to address 
> this issue.
> 1. TMessage adds a new field called "options"
> 2. customers set "options"
> 3. TExtendedBinaryProtocol writes "options" when "writeMessageBegin" invoked
> 4. TExtendedBinaryProtocol reads "options" when "readMessageBegin" invoked



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to