Original comment by @jaymode:
I was doing some experimenting using the custom realms and saw some interesting behavior. In the example custom realm, the authentication mechanism is not basic authentication but is a custom authentication "scheme" based on username and passwords in headers. The realm doesn't check for basic authentication, but when I provided valid credentials for the custom realm using basic auth and had the esusers realm enabled, I was able to authenticate. This is not the way it should work IMO.
This happened because the custom realm uses the provided UsernamePasswordToken. This token does not imply that it must be used for Basic authentication; if it did then this should be named a BasicAuthenticationToken. However, we have a lot of static methods in this token that deal with BasicAuthentication, so maybe we should split this into two classes?
What I am proposing is to change to our authentication service. Rather than iterating over all realms and calling the token method until we find one and then iterate over the realms again until the token is supported and can be authenticated, we do the following:
- A single loop in the Authentication service over the realms
token is called. If a token is returned, call authenticate. If authenticate returns a user, break the loop
- We keep track if a
token was returned by any realm. If there was no token, consider the request anonymous
- remove the
supports method in the realm since we do not need it anymore.
- create a
BasicAuthenticationToken that extends UsernamePasswordToken
In the case where there are multiple realms of the same type/token type, this means that we extract a token more than once. This requires more computation/memory but overall I don't think it will have that big of an impact and the authentication is correct.
Original comment by @jaymode:
I was doing some experimenting using the custom realms and saw some interesting behavior. In the example custom realm, the authentication mechanism is not basic authentication but is a custom authentication "scheme" based on username and passwords in headers. The realm doesn't check for basic authentication, but when I provided valid credentials for the custom realm using basic auth and had the esusers realm enabled, I was able to authenticate. This is not the way it should work IMO.
This happened because the custom realm uses the provided
UsernamePasswordToken. This token does not imply that it must be used for Basic authentication; if it did then this should be named aBasicAuthenticationToken. However, we have a lot of static methods in this token that deal with BasicAuthentication, so maybe we should split this into two classes?What I am proposing is to change to our authentication service. Rather than iterating over all realms and calling the
tokenmethod until we find one and then iterate over the realms again until the token is supported and can be authenticated, we do the following:tokenis called. If a token is returned, callauthenticate. Ifauthenticatereturns a user, break the looptokenwas returned by any realm. If there was notoken, consider the request anonymoussupportsmethod in the realm since we do not need it anymore.BasicAuthenticationTokenthat extendsUsernamePasswordTokenIn the case where there are multiple realms of the same type/token type, this means that we extract a token more than once. This requires more computation/memory but overall I don't think it will have that big of an impact and the authentication is correct.