-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic Auth with external authentication service #145
Comments
@giohappy which geoserver version are we targeting? |
I have no idea what "Basic Auth authentication through an external service" means? :-D |
@aaime here it is our use case. The AuthKey module permits to authenticate a user by parsing an authkey parameter. Then my intention is to map that user to its role by means of an AuthKey REST Roles service (which implements the roles and users endpoints) I would like to implement something similar for Basic Auth access. From my understanding Geoserver's Basic Auth filter only extracts username and password credentials from the request, then it delegates the authentication to the Authentication Providers. The available APs are "username and password" (which uses a UserGroups service to perform the authentication), "LDAP" and "JDBC". If I've misunderstood the Geoserver security concepts please correct me. |
@giohappy ok now it makes sense (well some, I don't know exactly how authkey works, I wrote it originally but it went through 2 full rewrites and does not work at all like it used to).
As far as I can see those end up doing two separate remote requests, and there is a caching mechanism in the middle to avoid doing too many requests. So if I understand correctly, you'd like to extract username and password from the basic auth, and then do remote calls to verify identity and grab roles. I don't know if it can be done with a single call, authkey does it with two following 1-1 the Spring Security architecture (which GeoServer uses with some customization). And I'm guessing the remote calls won't be the same expected by authkey? |
I don't know the internal details of AuthKey, but yes both AuthKey and geonode-oauth2 (which are the two modules we currently use) do two calls. First one authenticates the user and retrieves its rolenames and the second one binds them through their respective roles services. Roughly this is what happens (from our tests) AuthKey:
geonode-oauth2:
In the end it seems that these modules shortcut the configuration of Filters + Providers. Options:
|
@imranrajjad before you move on with this one wait for my initial investigation. |
@nmco understood |
Unfortunately I will have not time this or next week to perform the initial investigation, hence I will ask your help whit this @imranrajjad. Please have look at Giovanni and Andrea feedback and then let's have a quick chat. |
usual thing @imranrajjad:
|
Before sharing the plan and estimate, I am a bit unclear on the type of response which should be expected by the authenticating webservice. Is it a one time call which responds with roles already known to GS through available Role provider services? Or will it simply respond with a yes/no. If there is such a service available or atleast a specification is available, it will be really helpful. PlanWeb Authentication ProviderExtend ConfigurationA configuration UI that will allow users to define external URL with required place holder User can also configure how to handle response. The response handling will differ with the response content types. Initial estimate 3 days |
@imranrajjad have read the full story above? Have you reviewed how authkey works? In any case, you can ask details on the service counterpart to @giohappy but, mind you, we are not developing something specific for DJAM but something rather generic like what we have for authkey. Keep the discussion going here and keep @nmco in the loop. |
Summarizing the actions points (for you) that resulted from our call @imranrajjad:
Once we have a green light for one of the propose approaches, let's setup a detailed plan and review it, this will require a GSIP |
@imranrajjad and @nmco I don't know if a custom Authentication Filter would be ok here, as it was done for geonode-oauth2 and ApiKey, or if an Authentication Provider is the right way to go. In any case I fin that:
UserGroup Service Configuration For our use case having something simpler, similar to geonode-oauth, is fine, but I'll let @nmco express itself on this. |
@giohappy thanks for the detailed clarification, After going through the basic user:password based authentication and how authKey works. Below are my findings and a revised plan of implementation. Since these requirements do not involve key mechanism, hence this implementation will go in the core and not the authkey extension.
For processing roles, there can be two scenarios
To cater for both scenarios, the Provider GUI page can allow user to either configure a local service available in Geoserver or it can allow user to parse response to extract roles, again inspiration can be taken from how its being in authKey. Something similar to WebServiceBodyResponseUserGroupService.extractRoles but embeded inside the new Authorization Provider. This will handle both scenarios where a web service responds with authorities and where its just confirmation of credentials. I would be glad to hear everyone`s thoughts on this. |
@giohappy and @imranrajjad I don't understand nothing about GeoServer security authentication neither as a user, and certainly not code wise, so please read my comments taking that into consideration. That say, I had a quick read through the GeoServer documentation and based on this description from @giohappy :
It looks to me we have two needs:
Then there is this (insane) security system architecture, which seems to imply that roles can be obtained directly without have the groups service in the middle, but sometimes not. Long story short we (@nmco, @imranrajjad and @giohappy ) need to have a call tomorrow to discuss this to understand what's actually needed in the user perspective, what can we do to implement this and make it generic. |
@imranrajjad here below I attach an example from a working configuration of an AuthKey REST Roles Service Geoserver ConfigurationSample requestsUsers endpoint Request:
Response (partial view):
Roles and adminRole endpoints |
@nmco and @giohappy thanks for the meeting and clarification. Below please find the updated plan after our call yesterday. Litmus Test
With a correct regex to parse the user name from the response, I was able to use role services associated with all of the user groups and not just the Auth Key user groups. What this means in practice is that taking a username we can use any one of the available role services to authorize users. In case of Authkey mapper the user name is retrieved by providing the webservice with auth key. In the current scenario we will work with credentials directly instead of an key, hence this forces us to introduce an AuthorizationProvider. Implementation PlanAuthenticationTo understand the implementation plan, we can look at the example of authentication and authorization being done inside JDBCConnectAuthProvider. Where the credentials are passed to database for authentication purpose and a successful authentication is followed by Authorization using configured user group service. In current scenario we will replace Database with a configurable Web Service. Since we will be working in AuthorizationProvider, we will not require to parse username from the response as it is already available as part of credentials. AuthorizationSince we are working with Web service here, we can provide option to directly extract roles from web service response as being done in WebServiceBodyResponseUserGroupService.extractRoles. User can configure the regex in GUI and directly parse roles without delegating username to available Role services for simplicity. For using existing Role services, use of the API calls such as GUIUsing radio buttons user can navigate between direct role handling in web response and delegating authorization to existing services. Other options include mandatory web service configuration with placeholders and default admin role. |
@imranrajjad thanks for the analysis. I think it is a good plan. I'm not sure if your proposal is to implement both alternatives: extracting of roles from the web response or configuring a roles service. With regard to this do you confirm that extracting the roles from the web service response is enough? I supposed that a Roles Service was required in any case, and one of the reasons was to instantiate a RoleCalculator. |
|
Thank you for the plan @imranrajjad it matches indeed what we discuss during our meeting 👍. @giohappy the two options A few technical questions \ comments I have:
I have create this task sheet for the estimates, @imranrajjad make sure you create tasks for each independent functionality so @giohappy can pick what matches his budget. Take this into account when wrting the estimates:
|
sorry for the insistence but let me see if I understood it correctly.
It's not clear to me why the latter case (which might also be configured to use the default Roles service) doesn't need the roles from the webservice response, while the first requires them (and still uses the default Roles service). |
I made a new pull request with a branch that is a checkout from the one in the previous pr, and added some commits. |
@taba90 if I remember correctly the role services retrieve the actual admin role from a specific endpoint (see image below). This endpoint returns the role to be considered a Geoserver admin, independently from the ROLE_* convention. The convention of the ROLE_* prefix stems from the AuthKey module. It's exaplined inside AuthKEY WebService Body Response UserGroup Service ("Additional Options" sub-paragraph) |
thanks for the heads up @giohappy now its clear. Currently there is no possibility to specify a separate regex/path for the admin role in the new community module. |
I haven't asked anything :) |
@giohappy that is a good idea. |
the old pr is still open. If it is meant to be closed can some one do it? (I don't have permissions) geoserver#4483 |
Attaching here the 2.18.2 jar for test purpose |
@simboss test were already done on Friday. Michal confirms that it's working. |
perfect. @taba90 I have not checked the PR but I would want to see clear documentation provided as part of this PR. If we do not have it, please, open a seprate JIRA and add it in a separate PR. |
K, I see there is basic documentation but I am not sure it suffices. We need user documentation so that someone who wants to use this feature does not have to become crazy to understand how it works. |
I've reviewed the module, there are three significant issues. NamingFirst one is naming: it should not be called basic auth, it's confusing (I see this has been discussed above, but it's worth repeating). The security subsystem is complicated enough already, without adding extra confusion to existing terminology. The basic authentication is one of the ways a username/password can be provided to a server, and it's already managed by a core functionality, in the form of an authentication filter. What the module contains is an authentication provider, which takes an already populated Authentication object (populated by an auth filter) and calls onto an external service to validate the username/password. This is not different from the LDAP authentication or the JDBC connection authentications. See for reference the GeoSolutions training and the GeoServer own documentation Since the module documentation and the UI labels call it "Web Service authentication", I would call it that way, it's less confusing than "basic auth". Less secure than basic auth itselfBasic authentication is often critisized by being weak, but at least, it's base64 encoding the username and password to avoid accidental credential discovery by admins monitoring the network and the requests performed on it. This module instead sticks clear text usename and passwords straigth into the URL or in the headers, with no encoding whatsoever. This is quite bad, the people monitoring the network and services can be trusted, but having usernames and password appear as-is on their screen (where every by-standers can also see them) is unacceptable. Even if the admins were locked in a room alone, they are not necessarily the same people that are managing the user credentials, they should never be presented with them in such a casual way. Without asking to apply any actual security to it (e.g., encryption) let's at least be as good as basic auth, and base64 encode them? Please? HTTPS check is too weakThe code logs a warning if HTTP is used instad of HTTPS. Better than nothing, but the admin is playing ona GUI when that happens, not looking at the logs, so they won't see the warning. I recommend having an explicit GUI checkbox to allow HTTP connection usage (handy for quick testing I reckon), that an admin has to manually check in order to save a HTTP link. |
@aaime I totally agree with base64. This actually was required by myself long time ago in this comment. The comments don't collect all the discussion we had in the past on this thing, but I'm in favour of it of course. This will require some small chenages to DJAM for the decoding of a base64 encoded GET param, but it's straightforward. Just le us know how we wanto to name the parameter. I'm also fine with the forced checkd for HTTP usage. |
pr updated |
@giohappy the module has been merged on master.
I've already done some manual tests, but if before doing any backport you prefer to give a quick test another time in your environment, here is a 2.18.2 version of the plug-in. |
I will tell Michal inside the chat. |
@taba please backport. |
Back-ports merged, this will be available on the nightly builds starting tomorrow. |
cool, thx. Let's leave it open until @giohappy decides to start using it. |
@simboss I've opened another issue under support, because I'm not sure if it's something with the Basic Auth module or what else but things are far from working on dev and staging server. |
@simboss there is another issue created by @giohappy for the problem in question: Zdenek is already working on it. @giohappy I think this one should be closed. |
I would like to discuss the opportunity to implement Basic Auth authentication through an external service.
The idea is to have something similar to the "Key provider using an external service" offered by the Key authentication module.
I don't know the details of the Basic Auth implementation in Geoserver, but I suppose that implementing a Web Service Authentication Provider would be enough, very similar to the Key Provider:
The (optional) Api key will be used to authenticate the request.
User credentials (username and password) could be transmitted to the web service through a custom header, like. The standard Authorization header shouldn't be used though, because it semantics is different.
I would like to hear the opinions from @aaime and the others from the Geoserver team, since I will need to estimate the effort soon.
The text was updated successfully, but these errors were encountered: