IBM MQ Authentication and Authorization - authentication

According to my current understanding, all the client connections are authenticated at two levels, channel level and queue manger level,
At the queue manager level, it uses the CONNAUTH property's value of the QMGR which is an AUTHINFO object to determine how the authentication is done (Ex: Using host OS user repo), if the AUTHINFO object specifies ADOPTCTX(YES), it uses the user id contained in MQCSP structure as the user id for the application context and it is used for authorizations or if ADOPTCTX(NO) is there, the user id which the client application is running under is used as user id for the application context and that user id is used for authorizations.
At channel level, nothing regarding to authorizations is done. Only the authentication happens there as configured. For more granular access control, a set of channel authentication records are applied to the channels. CONNAUTH property's value of the QMGR is still used to determine the user repository to authenticate against.
Questions:
Am I correct up to this point? (corrections/explanations are much appreciated.)
What does the MCAUSER attribute of the channel object do? What is the purpose of it? Why does it matter which user the message channel agent runs under?
After all, how does the channel level authentication actually work with the MCAUSER?
In what order these two authentication procedures are done? Is the channel authentication done first?

You are correct that one should think about security of client connected MQ applications in two phases. There is an authentication phase (who are you? prove it!), and an authorization phase (now that I know who you are, are you allowed to do what you are trying to do?).
Authentication of a client connected MQ application can be done by checking the user id and password provided by the application (in the MQCSP) or by something at the channel level. This is essentially authenticating the channel connection, but it is inextricably linked to the client application. This channel authentication can use TLS certificates or a security exit to interrogate the remote party any way you feel like. [There is also IP address filtering but I wouldn't call that authentication so much].
The purpose of these authentications are to determine who the connecting party is (and reject them if necessary!) and to assign an appropriate user ID for the next step (the authorization checks). Assignment of this user ID can be done by accepting the password validated user ID (ADOPTCTX(YES)); by mapping certificate DNs (or IP addresses) using CHLAUTH rules; by setting the MCAUSER via a security exit; or by simply hard-coding a user ID into the MCAUSER (not authentication, but still a way to assign a user id for the later authorization checks). All of these have one thing in common, what they do ends up in the running SVRCONN's MCAUSER field. You can display it using DISPLAY CHSTATUS.
Authorization of a client connected MQ application happens just as it does for a locally bound MQ application. The same operations are checked against the same rules. Is this user allowed to "Open this Queue for putting", or "Inquire this QMgr object", or "subscribe to this topic" etc. The difference is simply in how the user ID used in that authorization check is obtained - i.e. how it gets into the MCAUSER.
To wrap up (and check I have covered all your questions):-
Sort of - read above text
The MCAUSER attribute at run-time holds the finally determined user ID for this client application. At definition time it can be hard-coded to a user id (some people use this to hard-code a rubbish user id as a belt-and-braces along side the CHLAUTH backstop rule).
Channel level authentication essentially sets the run-time value of MCAUSER
Authentication happens before authorization.
Further Reading
CHLAUTH – the back-stop rule
All the ways to set MCAUSER
Interaction of CHLAUTH and CONNAUTH - previously a blog post now incorporated into IBM Knowledge Center

Related

Communication microservice - Email verification Link

I have 2 microservices Identity & Communication. When user signs up, I want to send him an activation link to his email. Activation link is generated on Identity side, how can I pass it to Communication Microservice to send an email? or Communication microservice shoudn't exist as a separate microservice, but each microservice can use IEmailSender utility to send emails?
Communication Bounded Context is wrong for my system. Its just a technical Help SErvice which every Bounded Context should have in Order to fulfill its business capabilities. For example Identity in order to Activate Account needs this infrastructural posibility. Removed communication BC, and sending emails directly from Identity.
I typically have an endpoint that handles e-mails. I use my Shuttle.Esb open-source service bus to facilitate messaging but any service bus will do or you may opt for coding the messaging directly using something like RabbitMQ.
Integration between endpoints is handled by an orchestration endpoint for the bounded context in question. This orchestration layer would send a SendEMailCommand to the e-mail endpoint and then receive confirmation once the e-mail has been successfully dispatched. In this way there is a single point that handles e-mails.
When you have every bounded context access something like an IEMailGateway it means that you may need to do a bit more legwork in terms of getting the e-mail going since you need access to the relevant mail server and that may mean dealing with firewalls, ports, security

How does TLS Channel ID guarantee client authenticity?

I've read RFC draft for Channel ID. I've also read the earlier draft for OBC's, but I'm a little slow to follow. I understand that Google has implemented a new extension based on their earlier Channel ID work. I'm curious to learn what the benefits are and how they are accomplished, but I can't seem to find much detail on the topic from a systems perspective (I'm not a crypto man).
How does Channel ID guarantee the authenticity of a client machine in a SSL session?
Channel ID do not guarantee authenticity, but provides traceability.
It is based on a key pair generated for a specific domain, which is stored on the client, and reused for subsequent TLS connections. An application is then able to associate this Channel ID to a user session, and make sure this session is only used with this Channel ID.
Channel ID is thus a mean to track (for the sake of security) a given client, making it possible to ensure that an application session is not stolen and reused elsewhere.

Is this stateful web service/wcf service?

Service layer has a login method which accepts username and password and returns a unique session id (a guid) if the account is valid.
On subsequent request the same session id will be passed instead of passing username and password, so is this stateful or stateless, because I don't need any state information except the authentication of each request
The client connects, exchanges data, stores it somewhere, and disconnects. Upon subsequent connections the SAME DATA must be passed back to the server. This is not stateful.
In a stateful connection, you would connect, authenticate, and then simply use the service. The server would "remember" you without having to constantly be reminded of your session ID. This is definitely stateless.
I would say it could be considered stateful. The server is storing information regarding your session including client activity (timeout, etc). I could also see the argument especially in the Java world where stateless and stateful Beans are much more well defined.

Seeking input: maintaining a server session without any server state

I'm not a security expert, so I'm looking for people to poke gaping holes in an authentication scheme I've devised, or point me to a better, existing scheme that fulfills the same goals:
Overview of Problem
I have an interface in which the client maintains session lifecycle (it's an HTTP session on a web server, but it doesn't really matter).
The stateless server provides some services that require the caller to be authenticated (the server has the ability to perform this authentication).
However, it's desirable for the server not to have to authenticate the caller on each invocation, e.g., by passing credentials in each call. (The authentication process can be expensive.)
It's also desirable not to maintain session state on the server. For one thing, it's just asking for a brittle solution to have independent session timeouts on both client and server (the one on the client can't be gotten rid of), and a server timeout seems necessary in order to have a reliable session lifetime on the server (rather than relying on the client to explicitly end the session at an appropriate time). For another thing, the server isn't set up to store this sort of state.
The server has an explicit authenticate method. The problem is then: how does the server verify that, when another method is called, the caller has previously authenticated using the authenticate method, without storing any session state on the server?
Proposed Solution
Here's a scheme I've come up with:
The authenticate method accepts credentials as input parameters. Upon successful authentication, the server returns two things:
A timestamp indicating the time that authentication was performed.
An encrypted version of the tuple of { username, timestamp }, encrypted with a private key
On further method calls, the client passes both of these values back to the server. The server then decrypts the encrypted { username, timestamp } tuple. If the decrypted timestamp matches the unencrypted value that was also sent by the client, the server knows that the client has previously authenticated (as that's the only way to acquire a valid encrypted value). The decrypted username tells the server which user has been authenticated.
The validity period of an encrypted key can be enforced by only allowing timestamps that are within x hours of the current time. This isn't the same as a session timeout, but it limits the window within which a compromised timestamp could be used by a malicious party.
So
I fear that this scheme is naive in a dozen ways. What weaknesses or bad logic do you see?
In case anybody cares (which seems unlikely given the amount of attention this question has gotten!), we ended up implementing a scheme much as described above.
A few of the details vary, though:
The server creates a session token based upon the user name, the session-start timestamp (passed back to the user), and a salt.
The client does not pass this token back to the server. Instead, an MD5 hash is created from the entire request content concatenated with this token.
The MD5 hash is sent to the server along with the timestamp and the the user name (and the request). The server then re-creates the session token and performs the same hashing algorithm. If the MD5 hashes match: valid request.

How can I share one session between several wcf's clients?

I have several web services. One of this services is used for retrieve a session id (authentication). I pass this id when call other services through SessionInfo.
I want to use WCF instead of classic web methods. How can I share one session between several wcf's clients?
It is not clear what do you mean by session. WCF supports four types of sessions:
Transport session - for transport protocol which maintains session between server and client. For example: Net.Tcp, Net.Pipe
Reliable session - support for reliable in order delivery over unreliable channel if both client and server are running
Security session - client has to be authenticated only for the first call, subsequent calls are authenticated by session token. This session is also called security context.
Application session - this has a meaning for IsInitiating and IsTerminating parameters of operation contract and PerSession instancing. This session can be used only if any of preceding sessions is used as well = it can't be used in BasicHttpBinding because it doesn't support transport, reliable and security session.
All these sessions are related to communication between single client proxy and single service instance. Nothing else is provided out of the box. Moreover there is no special "session" object.
So what exactly are you trying to achieve? Are you going to replace ASMX services wich are using ASP.NET session? In that case check this sample.
Edit:
The idea about receiving single Id from the first service and reusing this Id on subsequent calls to multiple services should be called corelation (one big activity/transaction) or federation (security related) not session.
As marc_s says you cannot share the session.
But what you can do is to pass the session id as a parameter in your WCF calls, so that you know on whos behalf the call is being made.
Make sure that you use encryption on these calls.
The recommanded way to that is by manually maintaining session state between calls. You generate session IDs the way you want and load/persist session information into a database on every call using your own logic.
By doing that, you will support sessions in a way that will enable:
Load balancing
Session sharing
Fail over