Announcement Announcement Module
Collapse
No announcement yet.
Implement Login Dialog in Spring Rich Client Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Implement Login Dialog in Spring Rich Client

    Where should I put my login code, when I start my application I load some resources (e.g. available servers) and prompt user to login using his/her User Id and Password in the Dialog which extends ApplicationDialog

    My problem is if I put the Dialog code in new Thread (inside onPreStartup() method) and Join on this Thread then Dialog does not load properly. If I dont have this Dialog in a seperate thread then Background Splash screen doesnt refresh.

    Also I cant use the onPostStartup() method as the application reads userId from Login Dialog and loads the gui on the basis of it.

    So I am wondering what is a good way to implement custom login mechanism in a Spring Rich Client Application without major rearchitecting. Ideas, suggestions or pointers all welcome.

    Thanks,
    Amit

  • #2
    There is a standard LoginDialog available in Spring RCP. Don't know exactly tho how it completely works, I'll try and ask Jan if he can explain it's workings. I do know you just need to provide a loginCommand bean in your commands context. I'll see what I can find.

    I'm currently writing a tutorial on Spring RCP, so perhaps I'll put in the logindialog too.

    Comment


    • #3
      that will be great

      Thanks,
      Amit

      Comment


      • #4
        Just create this bean in your commands context:

        Code:
        <bean name="loginCommand" class="org.springframework.richclient.security.LoginCommand">
                <property name="displaySuccess" value="false"/>
        </bean>
        And create a authenticationManager bean in your main RCP context.

        You have to alter your ApplicationLifecycleAdvisor so it looks for the loginCommand in you command context and execute the command in the onCommandsCreated method.
        You'll see a login dialog appear when you start the application.

        For the authentication manager you can implement your own (implements AuthenticationManager) or for test purposes, you can use MockAuthenticationManager, it accepts every login.
        Last edited by LievenDoclo; Jun 4th, 2008, 10:20 AM.

        Comment


        • #5
          where can I find AuthenticationManager class, for some reason I cant find it in my jars build from my subversion repo

          Thanks,
          Amit

          Comment


          • #6
            It's not a class or interface, but a concept from Acegi. Here's my configuration as an example, which connects to a remote server to do the actual authentication.

            Code:
            <bean id="authenticationManager" 
            		class="org.acegisecurity.providers.ProviderManager">
            		<property name="providers">
            			<list>
            				<ref bean="remoteAuthenticationProvider"/> 
            			</list>
            		</property>
            	</bean>
            	
            	<bean id="remoteAuthenticationProvider"
            		class="org.acegisecurity.providers.rcp.RemoteAuthenticationProvider">
            		<property name="remoteAuthenticationManager" ref="remoteAuthenticationManager"/>
            	</bean>
            	
            	<bean id="remoteAuthenticationManager" 
            		class="org.springframework.richclient.security.remoting.BasicAuthHttpInvokerProxyFactoryBean" >
            		
            		<description>A proxy to the remote authentication manager</description>
            		<property name="serviceUrl" 
            			value="http://${securityServiceServerName}:${securityServiceHttpPort}${securityServiceContext}/remote/RemoteAuthenticationManager" />
            		<property name="serviceInterface" value="org.acegisecurity.providers.rcp.RemoteAuthenticationManager" />
            	</bean>
            and the wiki page is quite useful here also:

            http://opensource.atlassian.com/conf...y/RCP/Security

            Jonny

            Comment


            • #7
              LoginDialog Help Required

              I Can not make anything out of it. I am new to Rich Client Desktop Application. Please help. Give me complete code.

              Comment


              • #8
                Have you taken a look at the code in the dataeditor sample, as it provides an example on how to add a custom login dialog (in that case, JXLoginDialog) to the application.
                This is the command we are using in one of our applications:
                Code:
                public class LoginCommand extends ApplicationWindowAwareCommand {
                    private ApplicationSecurityManager applicationSecurityManager;
                    private JXLoginDialog jxLoginDialog;
                
                    @Override
                    protected void doExecuteCommand() {
                
                        jxLoginDialog = new JXLoginDialog(new LoginService()
                        {
                            @Override
                            public boolean authenticate(String name, char[] password, String server) throws Exception
                            {
                                Authentication auth = new UsernamePasswordAuthenticationToken(name, new String(password));
                                auth = applicationSecurityManager.doLogin(auth);
                                SecurityContextHolder.getContext().setAuthentication(auth);
                                return true;
                            }
                        }, null, null);
                        jxLoginDialog.setModal(true);
                        jxLoginDialog.setVisible(true);
                        if(jxLoginDialog.getStatus() != JXLoginPane.Status.SUCCEEDED)
                        {
                            System.exit(1);
                        }
                    }
                
                    public ApplicationSecurityManager getApplicationSecurityManager() {
                        return applicationSecurityManager;
                    }
                
                    public void setApplicationSecurityManager(ApplicationSecurityManager applicationSecurityManager) {
                        this.applicationSecurityManager = applicationSecurityManager;
                    }
                }
                In the commands context you inject the application security manager into the command.
                The application security manager looks something like this:
                Code:
                  <bean id="applicationSecurityManager" class="org.springframework.richclient.security.support.DefaultApplicationSecurityManager">
                    <property name="authenticationManager" ref="authenticationManager"/>
                  </bean>
                The authenticationManager bean is a Spring Security class (see the Spring Security manual for more detail).
                You can easily make your own dialog and plug it into the login command. The command is called in the onCommandsCreated hook of the LifecycleAdvisor of your application (if you're using a custom logincommand, you'll probably need to extend the default LifecycleAdvisor
                Code:
                ...
                    @Override
                    public void onCommandsCreated(ApplicationWindow window) {
                        super.onCommandsCreated(window);
                        ((ActionCommand) window.getCommandManager().getCommand("loginCommand")).execute();
                    }
                ...

                Comment


                • #9
                  Just a note because I didn't see anybody mention it yet: putting a Swing component in another thread besides the Swing EDT thread isn't going to work.

                  I assume the OP somehow solved his problem, but I don't want others making that mistake. Down that road lies madness.

                  Comment


                  • #10
                    Actually, the onCommandsCreated method of the advisor is executed on the EDT (called by the constructor of AbstractApplicationWindow), as is onPreStartup and onPostStartup. Unless off course you're starting up the RCP application without the ApplicationLauncher, in which case all bets are off .
                    If you're doubting EDT problems, use the Substance LaF. They have some nice checks into their API regarding non-EDT Swing component creation. For example, if you forget to add scope="prototype" to visual components like the DataEditor in your context, Substance will nag that you're trying to create a visual component on a non-EDT thread (Spring pre-initializes singletons on context load...)

                    Comment


                    • #11
                      Originally posted by LievenDoclo View Post
                      Actually, the onCommandsCreated method of the advisor is executed on the EDT (called by the constructor of AbstractApplicationWindow), as is onPreStartup and onPostStartup. Unless off course you're starting up the RCP application without the ApplicationLauncher, in which case all bets are off .
                      If you're doubting EDT problems, use the Substance LaF. They have some nice checks into their API regarding non-EDT Swing component creation. For example, if you forget to add scope="prototype" to visual components like the DataEditor in your context, Substance will nag that you're trying to create a visual component on a non-EDT thread (Spring pre-initializes singletons on context load...)
                      I wasn't doubting Spring RCP - it was this, in the first post, that caught my eye:

                      My problem is if I put the Dialog code in new Thread (inside onPreStartup() method) and Join on this Thread then Dialog does not load properly. If I dont have this Dialog in a seperate thread then Background Splash screen doesnt refresh.
                      I saw no mention of a SwingWorker, Spin, FoxTrot, or coordinating with the EDT, so I thought I would mention it - especially since he mentioned that the dialog did not display properly (which is often seen in Swing threading problems).

                      Even though the methods you mention execute on the EDT, if you start another thread inside them and manipulate Swing components in that other thread, you are outside the aegis of the EDT and have to take that into account (or preferably, just don't do that).

                      Now maybe the OP knows this, maybe others do to - but there are plenty of people who don't despite it being said over and over again, so I thought I would say it once again.

                      As for Substance, I am a believer in using the native L&F wherever possible, unless there is a compelling reason not to. I think one of the reasons Java desktop apps have had acceptance problems is due to the use of non-native L&Fs where not necessary. Simply because it can be done doesn't mean it should be done.

                      Having checks for executing on the EDT is a good thing. I've sprinkled these throughout Swing code in the past and will in the future. I think it is something that should be in the core Swing SDK, but with the ability to turn it off (we turned it on during dev and testing, then turned if off when we released/deployed).

                      Comment


                      • #12
                        Doubt in Code

                        Thanks for your reply. I Still have some queries, hope will get the same response from you.


                        1) Is JXLoginDialog extends any special class or JDialog?
                        2) Could not find Authentication Class & SecurityContextHolder.
                        3) How to check the credentials with database Table values.
                        4) As per declaration applicationSecurityManager requires a property applicationSecurityManager. But the declaration jwray, it seems it calls some web based servlet, how to call desktop method..?

                        Sorry for my limited knowledge.

                        Comment


                        • #13
                          To answer your questions:

                          1) JXLoginDialog is a part of SwingX, latest version is 1.0

                          2) Authentication and SecurityContextHolder are a part of Spring Security. You'll need to add those jars.

                          3) Take a look at the Spring Security manual. You need to create an AuthenticationManager with one or more providers. Since you're using a database, you'll probably need a DaoAuthenticationProvider, that needs an implementation of a UserDetailsService. That implementation then does the check in the database. Hehe, that was a handful.

                          4) The ApplicationSecurityManager is just a RCP class that needs a ZuthenticationManager. In Jonny's example his AuthenticationManager has been remoted through HttpInvoker. If your client runs standalone (server and client in the same Spring container) you'll have access to the AuthenticationManager directly, but in a client-server environment, that service will probably be remoted. Take a look at the Spring remoting chapter in the manual for more information.

                          Comment


                          • #14
                            lol

                            Thanks a lot

                            Comment


                            • #15
                              Login example

                              Has anyone got an simple example of integrating Spring security with the Spring Rich Client?

                              I think it would be a good task to add it to the sample applications that come with Spring-RC.

                              Many thanks.

                              Comment

                              Working...
                              X