Sunday, January 07, 2007

IP-based Authentication in WebLogic

Some time ago I was asked to make certain some usernames could only be authenticated if tried from specific known IP-addresses. The application is running on a WebLogic server, and we are already running our own custom AuthenticationProvider and AuthorizationProvider.

It turned out getting to know the IP address of the incoming client request to authenticate was quite difficult. Actually, the WebLogic SSPI APIs for the Authentication part did not allow us to get the IP address.

Okay, so I thought I could simply put the IP address on some thread local storage in a WebLogic ConnectionFilter implementation and then access it from the Authentication implementation. But, guess what, the ConnectionFilter implementation and the SSPI implementation for a user request does not execute on the same thread, rendering the thread local solution useless.

Hmm, what then. I - briefly - thought about creating a servlet filter that could throw off the sensitive users after authentication but before application logic. It would work, but had several drawbacks
  • I - and others - would have to remember to mount the filter, and do it correctly, before any actual application logic
  • The sensitive user would actually be allowed login from a non-allowed IP before being thrown off
Back to the drawing board. After some googling and talking to WebLogic support, I found a feature in the Authorization part of the code. When a resource is authorized in WebLogic, at some point WebLogic calls our AccessDecision.isAccessAllowed(...) and among the parameters is the ContextHandler.

Basically, a ContextHandler is a Map like object, which contains "context information" from the request, which can be used in the process of authorization of the given resource. When the resource is a URLResource, a HttpServletRequest can be found in the ContextHandler which makes it possible to obtain the IP address.

So, the final solution ended up checking IP address and username against known IP ranges, all at authorization time. Sadly, this is still after authentication, but we simply could find no other solution inside the WebLogic SSPI APIs.

7 comments:

Dąbek said...

Hi,

I'm trying to get host IP in my LoginModule, and I can't do that. Can you send me your code exaple?
Or help on other way?
You can also reply me in topic on weblogic forum at this link http://forums.bea.com/thread.jspa?threadID=300003287.

Regards,
Marcin Dąbrowski

Per Olesen said...

@marcin:

I can give you some code of my solution, but I am not sure it is what you are looking for. You are talking about getting the IP in your LoginModule, and my solution is to access it in the authorization phase, which comes next.

Here is an abstract from the AuthorizationProvider implementation I have plugged into weblogic (missing null checks and all that):

public class AuthorizationProviderImpl implements DeployableAuthorizationProvider, AccessDecision {

.....

public AccessDecision getAccessDecision() {
return this;
}

public Result isAccessAllowed(Subject subject, Map roles, Resource resource, ContextHandler contextHandler, Direction direction) throws InvalidPrincipalException {
Result result = Result.ABSTAIN;
if (resource != null && resource instanceof URLResource) {
URLResource urlResource = (URLResource) resource;
HttpServletRequest request = (HttpServletRequest) contextHandler.getValue("HttpServletRequest");
String remoteIp = request.getRemoteAddr();
String remoteUser = request.getRemoteUser();

if (doCheckOnIpHere(remoteIp, remoteUser)) {
result = Result.PERMIT;
}
else {
result = Result.DENY;
// maybe get Session from HttpServletRequest and invalidate it
}
}
return result;
}

.....
}

Now, it has been some time since I last had a look at this, but as I remember it, LoginModule is something that is used at authentication time, before authorization time. I found no good way at getting the IP there at that time.

Karima said...

Why don't you develop a custom euthentication provider based on the ip address.

Tech Per said...

@Karima: Yes, that is exactly what we would like. The question is how to access the IP of the entity to be authenticated, inside the custom Authenticator implementation. Have you done this before and if so, how?

Karima said...

I'm trying to do it.
And yes the question is how to get the ip address in the loginModule.
I have the IP in the request but I don't know how to get in the callback
any tips ??

Tech Per said...

Nope, no idea how to get access to the IP in the LoginModule implementation. Sorry. (but I would like to know it :-)).

BTW: What do you mean by "I have the IP in the request ..." ?

yagmurunsesi said...

thanks
renovationdoctors.com
turizmseyahat.blogspot.com
www.yagmurunsesi.org
yagmurunsesiorg.blogspot.com
turkuntarihi.blogspot.com
websitesiyapamak.blogspot.com
saglik-k.blogspot.com
ders-hane.blogspot.com