Archived

This forum has been archived. Please start a new discussion on GitHub.

service access control problem

Hi, I want to develop a common service (which provide sending and receiving MMS service) for other server(eg. web server).
I think ICE is rather a good solution to do this.

Send progress:
web servers ---->|
web servers ---->| -> MMS Service -> MMS Gateway
web servers ---->|

Recv progress:
web servers <----|
web servers <----| <- MMS Service <- MMS Gateway
web servers <----|


I simply define a sending MMS interface:

class SendMMS
{
SendMMSRes SendMMS(TMMSInParam inparam);
}

but I have 3 questions:

1. When multi web server invocation the SendMMS operation, are there multi SendMMS impletion objects for each web server or only one?

2. The authrization is needed for every web server to access my MMS service, how can I control the access? Must I provide another IN PARAM in the SendMMS operation which include authrization information? And do the authrization in every call?

3. When receive MMS from the MMS gateway, each MMS must be deliver to one of those web servers based some policy (eg. by destnation ID). So for receiveing MMS service, I have to make the web servers as the serverside of ICE object. But if I do so, then there is many same object in different web servers, and they are different. I don't know how to config ICE to fit this solution.

Rather sorry for my poor English.

yomi

Comments

  • marc
    marc Florida
    Re: service access control problem
    Originally posted by yomi

    class SendMMS
    {
    SendMMSRes SendMMS(TMMSInParam inparam);
    }

    Note that you cannot give an operation the same name as its interface or class. That's because you will get a name clash with the generated class constructor.
    Originally posted by yomi

    1. When multi web server invocation the SendMMS operation, are there multi SendMMS impletion objects for each web server or only one?

    The simplest solution would be just one. All web servers invoke requests on one single SendMMS Ice object, using the same proxy.

    If you need an object per web server, then you have to implement a factory, so that each web server can create its own SendMMS Ice server.
    Originally posted by yomi

    2. The authrization is needed for every web server to access my MMS service, how can I control the access? Must I provide another IN PARAM in the SendMMS operation which include authrization information? And do the authrization in every call?

    This depends on how "trusted" your back-end network is. If it is trusted, and you want an authentication mechanism more for logging or to avoid mistakes (but not to avoid hacker attacks), then passing some kind of authorization ID as extra parameter is the simplest solution.

    Instead of the extra parameter, you could also use the request context. You could set a default context for the proxy once, so that it contains the authorization ID, and then wouldn't have to pass it explicitly anymore.

    If the back-end network is not trusted, then you should use Glacier, which is the Ice firewall solution. Glacier can do all the authentication for you. Please see the Ice manual for details. But if the network is trusted already, Glacier would be an overkill.
    Originally posted by yomi

    3. When receive MMS from the MMS gateway, each MMS must be deliver to one of those web servers based some policy (eg. by destnation ID). So for receiveing MMS service, I have to make the web servers as the serverside of ICE object. But if I do so, then there is many same object in different web servers, and they are different. I don't know how to config ICE to fit this solution.

    You could either use a hand-written look-up mechanism, that returns the correct proxy for the Ice object in one of the web servers, based on a destination ID. Or you could employ IcePack for that, the Ice location and activation service.

    In the latter case, your web servers would create indirect proxies, meaning that when you invoke on a proxy from the SendMMS server, then the SendMMS server would first ask IcePack for the destination, and then call the Ice object in one of your web servers. Please see the Ice manual for more information on IcePack.
  • Thank you , marc.

    Instead of the extra parameter, you could also use the request context. You could set a default context for the proxy once, so that it contains the authorization ID, and then wouldn't have to pass it explicitly anymore.

    Does 'request context' mean I provide another interface such as Login(authid) and must first invoke this operation? But how to set the context if there is only one server object for multi clients, since the server can on longer ditiguished the client's invoke in the SendMMS operation because SendMMS operation didn't take any authrization information?

    yomi
  • marc
    marc Florida
    Originally posted by yomi
    Thank you , marc.


    Instead of the extra parameter, you could also use the request context. You could set a default context for the proxy once, so that it contains the authorization ID, and then wouldn't have to pass it explicitly anymore.

    Does 'request context' mean I provide another interface such as Login(authid) and must first invoke this operation? But how to set the context if there is only one server object for multi clients, since the server can on longer ditiguished the client's invoke in the SendMMS operation because SendMMS operation didn't take any authrization information?

    yomi

    No, you simply create a context in the client, and set it as default context:
    std::string authID = ... // Your ID for authentication.
    SendMMSPrx proxy = ... // Your SendMMS proxy.
    
    Ice::Context ctx;
    ctx["authID"] = authID;
    proxy = SendMMSPrx::uncheckedCast(proxy.ice_newContext(ctx));
    

    Then you can simply invoke on the proxy, and the default context will always be passed along with every operation call. On the server side, you can access the context as follows:
    void SendMMS::someOperation(..., const Ice::Current& current)
    {
            Ice::Context::const_iterator p = current.ctx.find("authID");
             if(p == current.ctx.end())
             {
                   // Context not set, handle with exception or in any other apropriate way...
             }
             else
             {
                    std::string authID = p->second;
                     // Use authID to check authorization...
             }
    };
    
  • Thank you again, marc.

    I think my problem is resolved with your help.

    By the way, can the severant get the client's ADDRESS information(ip, port, transfer protocol ) in the dispatch call back function? Maybe from the 'Ice.Current __current' param?
    I have checked the Ice.Current class, but didn't get the address information.
    struct Current
    {
    ::Ice::ObjectAdapterPtr adapter;

    ::Ice::Identity id;

    ::Ice::FacetPath facet;

    ::std::string operation;

    ::Ice::OperationMode mode;

    ::Ice::Context ctx;

    ICE_API bool operator==(const Current&) const;
    ICE_API bool operator!=(const Current&) const;
    ICE_API bool operator<(const Current&) const;
    };
  • marc
    marc Florida
    No, there is no way to access the caller's IP address.
  • Oh, I think the caller's ip is a usefull information in many case.
    For example when the server must know whether the client is behind firewall, the caller itself can't provide the information.
  • marc
    marc Florida
    I agree, this is something we should add in a future version.