Oh. that makes it totally different. You have a custom authentication backend. I missed that.
When you use the Container+web.xml for security management, the signon process is done externally. Your app nevers see the user ID or password. In fact, you never actually get notified when you've been logged in. When the app container detects a need for an authenticated user, regardless of where you are in the app, it does this:
1. Puts the current page request on hold
2. Presents the login page that you defined in web.xml (assuming form-based logins)
3. Reads the userId and password from the login form
4. Passes them to the security Realm and gets back a go/no-go indication.
If the authentication succeeds, a UserPrincipal object gets constructed and attached to your HttpServletRequest and the derailed page request is resumed. If the authentication fails, the loginfail page is displayed and the process repeats until the user logs in successfully or gives up.
The actual login code is part of the security Realm, which is server-dependent. It's not difficult to write a security Realm package, but the Realm isn't part of the webapp (it is, after all, CONTAINER managed security). In your case, you'd have to have a custom Realm that invoked the web service. The Realm classes have to be places in the Tomcat server classpath (NOT in the application WAR), and the server.xml file has to be customized to define the custom Realm. I've done this for a web service, but security code is less forgiving than application code and when you start talking about customizing the server itself, sometimes people get a little excited. So you may just have to do this the hard way.
In a shop that's truly dedicated to security, a custom security Realm would be a good investment. However, few shops are dedicated to security, as you may have noticed in the headlines over the last several years. To get much of the same benefits of container-managed security without modifying the server, you can create a
servlet filter to scan for protected URLs just like the container does. The difference here is that filters generally don't intercept and restart URL requests, you have to write and debug your own security code - including the interceptor code - and the security settings in web.xml aren't used.
The most common approach of all, alas, is where "code toads" put security code directly into the application logic itself. Except when they forget to. Or someone comes along later and changes things and doesn't understand how the security code worked. Because the security system is a one-off job that's not documented in a book down at the local Barnes&Noble. Or the security system gets changed and suddenly 47 separate and widely-disconnected parts of the application all break at once. Well, actually, it was 48, but no one will know that until December. And this lovely state of affairs is probably what you're going to get stuck doing unless you happen to work in a place where someone like me takes exception and sets up a proper security realm (and has the clout to get it made part of the shop standards).
A "code toad", BTW is someone hired to be cheap, not good who, can produce many lines-of-code very fast (because lines-of-code are things that bean counters can appreciate). As opposed to fewer, more efficient, more reliable (and more secure) lines of code. Not all DIY security is done by code toads, but code toads don't know any other way to do things. Otherwise they wouldn't be code toads. And there are a lot of code toads out there.
Just one final comment. Its VERY bad practice to have a security server send out the password to the security client. Even when the password's encrypted. And, in fact, a whole security paradigm revolves around passwords that
can't be decrypted (one-way encryption). Best practice is that the client establishes a secure, encrypted channel to the server and sends the credentials to the security server, which then securely accepts/rejects them. In the Tomcat
JDBC and DataSource security realms, they can hash the password and do a "SELECT COUNT(*) FROM user WHERE user_id = ? AND password = ?", where the hashed password is stored in the database. If the returned count is 1, the user passed. If 0, the signon failed. If > 1, someone needs to take a look at the database. That way, the password is never seen in plain text inside the database or returned to the webapp server.