[ 
https://issues.apache.org/jira/browse/GERONIMO-4848?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Quintin Beukes updated GERONIMO-4848:
-------------------------------------

    Description: 
When an application client is configured to authenticate with a JAAS realm and 
a CallbackHandler, the login is performed before the application's main method 
is called, thus outside the context of the client application itself.

This all works, except a failed login isn't retried and there is no way for the 
application to even detect this (nor a cancel if such an option existed).

The attached patch is a modification of 
org.apache.geronimo.openejb.OpenejbRemoteLoginModule.

- It introduces a login retry facility. It does so by supplying an optional 
extra "option", which can be specified in the gbean configuration, like so:
...
        <lc:login-module control-flag="REQUIRED">
          <lc:login-domain-name>remote-openejb-realm</lc:login-domain-name>
          
<lc:login-module-class>net.kunye.platform.security.auth.ApplicationClientLoginModule</lc:login-module-class>
          <lc:option name="RemoteSecurityRealm">KMSRealm</lc:option>
          <lc:option name="ServerURI">ejbd://localhost:4201</lc:option>
          <lc:option name="FailedLoginTries">3</lc:option>
        </lc:login-module>
...

- If you omit this option, it will default to the current behaviour of "1" try.

- If you supply an invalid value for an option (any value that would raise a 
NumberFormatException when calling "Integer.parseInt()"), it will default to 
the current behaviour of "1" try.

- If you specify an integer great or equal to 0, it will perform the given 
amount of tries. If no successful authentication occurred during these tries it 
will fail with the FailedLoginException (as it does currently).

- If you specify 0 login tries, then it will keep trying until either a 
successful authentication or the user cancelled. The cancel is detected by 
setting either the NameCallback or PasswordCallback's value to null. This is 
quite unintuitive and might make it more difficult to find bugs in your code 
where the values are unintentionally null, so an alternative way might be 
better. 

Note: The "cancel" check works for all logins, including the first try. 

- Further, if a "cancel" is detected, the callback handler is invoked with a 
single TextOutputCallback which contains an INFORMATION type message "Login 
cancelled by user.".

- If authentication failed, the callback handler is invoked with a single 
TextOutputCallback which contains an ERROR type message "Login failed for user: 
${USER}", where USER is the username of the last NameCallback.

The justification of implementing this in the LoginModule and not the 
application client is to have more direct access to the CallbackHandler, so as 
to send the "Login Failed" and "Login canceled" messages. Also the fact that 
certain types of login modules might be used which don't support the "concept" 
of a retry, like host based authentication modules. So doing retries in the 
application client layer didn't seem logical. This way you can also extend the 
class or build your own and ship it with your application, and so be able to 
customize the retry behaviour, instead of relying on a fixed retry strategy in 
the application client layer (which could only be changed by recompiling the 
plugin).

Any suggestions/requests, just let me know and I'll implement them.

  was:
When an application client is configured to authenticate with a JAAS realm and 
a CallbackHandler, the login is performed before the application's main method 
is called, thus outside the context of the client application itself.

This all works, except a failed login isn't retried and there is no way for the 
application to even detect this (nor a cancel if such an option existed).

The attached patch is a modification of 
org.apache.geronimo.openejb.OpenejbRemoteLoginModule.

- It introduces a login retry facility. It does so by supplying an optional 
extra "option", which can be specified in the gbean configuration, like so:
...
        <lc:login-module control-flag="REQUIRED">
          <lc:login-domain-name>remote-openejb-realm</lc:login-domain-name>
          
<lc:login-module-class>net.kunye.platform.security.auth.ApplicationClientLoginModule</lc:login-module-class>
          <lc:option name="RemoteSecurityRealm">KMSRealm</lc:option>
          <lc:option name="ServerURI">ejbd://localhost:4201</lc:option>
          <lc:option name="FailedLoginTries">3</lc:option>
        </lc:login-module>
...

- If you omit this option, it will default to the current behaviour of "1" try.

- If you specify an integer great or equal to 0, it will perform the given 
amount of tries. If no successful authentication occurred during these tries it 
will fail with the FailedLoginException (as it does currently).

- If you specify 0 login tries, then it will keep trying until either a 
successful authentication or the user cancelled. The cancel is detected by 
setting either the NameCallback or PasswordCallback's value to null. This is 
quite unintuitive and might make it more difficult to find bugs in your code 
where the values are unintentionally null, so an alternative way might be 
better. 

Note: The "cancel" check works for all logins, including the first try. 

- Further, if a "cancel" is detected, the callback handler is invoked with a 
single TextOutputCallback which contains an INFORMATION type message "Login 
cancelled by user.".

- If authentication failed, the callback handler is invoked with a single 
TextOutputCallback which contains an ERROR type message "Login failed for user: 
${USER}", where USER is the username of the last NameCallback.

The justification of implementing this in the LoginModule and not the 
application client is to have more direct access to the CallbackHandler, so as 
to send the "Login Failed" and "Login canceled" messages. Also the fact that 
certain types of login modules might be used which don't support the "concept" 
of a retry, like host based authentication modules. So doing retries in the 
application client layer didn't seem logical. This way you can also extend the 
class or build your own and ship it with your application, and so be able to 
customize the retry behaviour, instead of relying on a fixed retry strategy in 
the application client layer (which could only be changed by recompiling the 
plugin).

Any suggestions/requests, just let me know and I'll implement them.


> Application Client Login Retries
> --------------------------------
>
>                 Key: GERONIMO-4848
>                 URL: https://issues.apache.org/jira/browse/GERONIMO-4848
>             Project: Geronimo
>          Issue Type: New Feature
>      Security Level: public(Regular issues) 
>          Components: application client, security
>    Affects Versions: 2.1.4
>            Reporter: Quintin Beukes
>            Priority: Minor
>         Attachments: login-retries.patch, OpenejbRemoteLoginModule.java
>
>
> When an application client is configured to authenticate with a JAAS realm 
> and a CallbackHandler, the login is performed before the application's main 
> method is called, thus outside the context of the client application itself.
> This all works, except a failed login isn't retried and there is no way for 
> the application to even detect this (nor a cancel if such an option existed).
> The attached patch is a modification of 
> org.apache.geronimo.openejb.OpenejbRemoteLoginModule.
> - It introduces a login retry facility. It does so by supplying an optional 
> extra "option", which can be specified in the gbean configuration, like so:
> ...
>         <lc:login-module control-flag="REQUIRED">
>           <lc:login-domain-name>remote-openejb-realm</lc:login-domain-name>
>           
> <lc:login-module-class>net.kunye.platform.security.auth.ApplicationClientLoginModule</lc:login-module-class>
>           <lc:option name="RemoteSecurityRealm">KMSRealm</lc:option>
>           <lc:option name="ServerURI">ejbd://localhost:4201</lc:option>
>           <lc:option name="FailedLoginTries">3</lc:option>
>         </lc:login-module>
> ...
> - If you omit this option, it will default to the current behaviour of "1" 
> try.
> - If you supply an invalid value for an option (any value that would raise a 
> NumberFormatException when calling "Integer.parseInt()"), it will default to 
> the current behaviour of "1" try.
> - If you specify an integer great or equal to 0, it will perform the given 
> amount of tries. If no successful authentication occurred during these tries 
> it will fail with the FailedLoginException (as it does currently).
> - If you specify 0 login tries, then it will keep trying until either a 
> successful authentication or the user cancelled. The cancel is detected by 
> setting either the NameCallback or PasswordCallback's value to null. This is 
> quite unintuitive and might make it more difficult to find bugs in your code 
> where the values are unintentionally null, so an alternative way might be 
> better. 
> Note: The "cancel" check works for all logins, including the first try. 
> - Further, if a "cancel" is detected, the callback handler is invoked with a 
> single TextOutputCallback which contains an INFORMATION type message "Login 
> cancelled by user.".
> - If authentication failed, the callback handler is invoked with a single 
> TextOutputCallback which contains an ERROR type message "Login failed for 
> user: ${USER}", where USER is the username of the last NameCallback.
> The justification of implementing this in the LoginModule and not the 
> application client is to have more direct access to the CallbackHandler, so 
> as to send the "Login Failed" and "Login canceled" messages. Also the fact 
> that certain types of login modules might be used which don't support the 
> "concept" of a retry, like host based authentication modules. So doing 
> retries in the application client layer didn't seem logical. This way you can 
> also extend the class or build your own and ship it with your application, 
> and so be able to customize the retry behaviour, instead of relying on a 
> fixed retry strategy in the application client layer (which could only be 
> changed by recompiling the plugin).
> Any suggestions/requests, just let me know and I'll implement them.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to