12 Replies Latest reply on Mar 15, 2013 1:51 PM by rruss

    custom errai.authentication_adapter

    juandavidr

      Hi all,

       

      I'm new to errai and i'm trying to use the authentication methods wich will help me secure my app. i've tryied to use both, a custom Authentication adapter, and the JAASAdapter provided by errai, but i havent been able to get the bus to authenticate, is there somthing i'm missing?  i'm always getting the following error:

       

       

      16:56:07,984 ERROR [STDERR] Exception in thread "Thread-17" java.lang.RuntimeException: scheduler interrupted by exception

      16:56:07,984 ERROR [STDERR]     at org.jboss.errai.bus.server.async.SimpleSchedulerService.run(SimpleSchedulerService.java:87)

      16:56:07,984 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:662)

      16:56:07,984 ERROR [STDERR] Caused by: org.jboss.errai.bus.client.api.base.NoSubscribersToDeliverTo: no subscribers to deliver to for subject: LoginCli

      ent

      16:56:07,984 ERROR [STDERR]     at org.jboss.errai.bus.server.ServerMessageBusImpl.delayOrFail(ServerMessageBusImpl.java:388)

      16:56:07,984 ERROR [STDERR]     at org.jboss.errai.bus.server.ServerMessageBusImpl.enqueueForDelivery(ServerMessageBusImpl.java:496)

      16:56:07,984 ERROR [STDERR]     at org.jboss.errai.bus.server.ServerMessageBusImpl.access$1000(ServerMessageBusImpl.java:49)

      16:56:08,000 ERROR [STDERR]     at org.jboss.errai.bus.server.ServerMessageBusImpl$8.run(ServerMessageBusImpl.java:499)

      16:56:08,000 ERROR [STDERR]     at org.jboss.errai.bus.server.ServerMessageBusImpl$6.run(ServerMessageBusImpl.java:403)

      16:56:08,000 ERROR [STDERR]     at org.jboss.errai.bus.server.async.TimedTask.runIfDue(TimedTask.java:104)

      16:56:08,000 ERROR [STDERR]     at org.jboss.errai.bus.server.async.SimpleSchedulerService.runAllDue(SimpleSchedulerService.java:124)

      16:56:08,000 ERROR [STDERR]     at org.jboss.errai.bus.server.async.SimpleSchedulerService.run(SimpleSchedulerService.java:76)

      16:56:08,000 ERROR [STDERR]     ... 1 more

       

       

      i'm using errai 1.3.2-Final gwt-2.4.0 and jboss 6.1 and a custom login module for JAAS.

       

       

      the following is my config:

       

      ErraiService.properties:

       

      ##

      ## Specify the Authentication/Authorization Adapter to use

      ##

      #errai.authentication_adapter=com.heinsohn.front.client.security.FOTAdaptadorAutenticacion

      errai.authentication_adapter=org.jboss.errai.bus.server.security.auth.JAASAdapter

       

       

      ##

      ## This property indicates whether or not authentication is required for all communication with the bus.  Set this

      ## to 'true' if all access to your application should be secure.

      ##

      errai.require_authentication_for_all=true

       

       

      #

      # (Optional) A Login MOTD sendNowWith be sent sendNowWith the client upon successful login.

      #

      errai.login_motd=UNAUTHORIZED ACCESS IS PROHIBITED!

       

      login.config:


      Login {

                com.heinsohn.front.services.core5.security.FOTLoginModule required ;

                org.jboss.security.ClientLoginModule required useFirstPass=true;

       

      };

       

       

      web.xml

      <?xml version="1.0" encoding="UTF-8"?>

      <web-app id="WebApp_ID" version="2.4"

                xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

                <listener>

                          <listener-class>com.heinsohn.front.web.server.LanzarCiclo</listener-class>

                </listener>

                <servlet>

                          <servlet-name>ErraiServlet</servlet-name>

                          <servlet-class>org.jboss.errai.bus.server.servlet.DefaultBlockingServlet</servlet-class>

                          <load-on-startup>1</load-on-startup>

                </servlet>

                <servlet-mapping>

                          <servlet-name>ErraiServlet</servlet-name>

                          <url-pattern>*.erraiBus</url-pattern>

                </servlet-mapping>

       

                <!-- Default page to serve -->

                <welcome-file-list>

                          <welcome-file>front-view.html</welcome-file>

                </welcome-file-list>

                <security-constraint>

                          <display-name>Accept only authenticated users</display-name>

                          <web-resource-collection>

                                    <web-resource-name>All files</web-resource-name>

                                    <url-pattern>/*</url-pattern>

                                    <http-method>POST</http-method>

                                    <http-method>GET</http-method>

                          </web-resource-collection>

                          <auth-constraint>

                                    <role-name>Guest</role-name>

                                    <role-name>Admin</role-name>

                                    <role-name>User</role-name>

                          </auth-constraint>

                </security-constraint>

                <login-config>

                          <auth-method>BASIC</auth-method>

                          <realm-name>FOTLoginModule</realm-name>

                </login-config>

                <security-role>

                          <role-name>Guest</role-name>

                </security-role>

                <security-role>

                          <role-name>Admin</role-name>

                </security-role>

                <security-role>

                          <role-name>User</role-name>

                </security-role>

      </web-app>

       

       

       

       

        • 1. Re: custom errai.authentication_adapter
          cbrock

          Sorry for taking so long to get back to you on this. Documentation on how to implement a LoginClient will be coming soon.

           

          Essentially you must implement a client-side service called "LoginClient" to handle the security challenge from the server.

          • 2. Re: custom errai.authentication_adapter
            juandavidr

            Tried to  do that but wouldn't work, i'm now implementeing my own security on the app since i could'nt get this to work.

            • 3. Re: custom errai.authentication_adapter
              nva

              Hi Mike,

               

              for the time being, would it be possible to post some sample source code to illustrate the implementation of the LoginClient? Doesn't have to be a full article, just a class or two. Looking at the Errai sources, implementing the server-side seems very straight forward. It gives some idea on the client side too, but some crucial wiring is still missing.

               

              Many thanks!

              • 4. Re: custom errai.authentication_adapter
                cbrock

                One good place would be to look at our unit test for the functionality:

                 

                https://github.com/errai/errai/blob/master/errai-bus/src/test/java/org/jboss/errai/bus/client/tests/BusCommunicationTests.java#L320

                 

                The general idea of the approach is that you attempt to signal a secured service, and if you don't have the required credentials, the LoginClient in the client is signalled notifying the client that authentication is required.

                 

                        ErraiBus.get().subscribe("LoginClient", new MessageCallback() {

                          @Override

                          public void callback(Message message) {

                            if (message.getCommandType().equals("FailedAuth")) {

                              fail("failed to authenticate with server");

                            }

                            else if (message.getCommandType().equals("SuccessfulAuth")) {

                              new CommunicationTasks().tryCommunication();

                            }

                            else {

                              MessageBuilder.createConversation(message)

                                      .subjectProvided()

                                      .command(SecurityCommands.AuthRequest)

                                      .with(MessageParts.ReplyTo, "LoginClient")

                                      .with(SecurityParts.Name, "test")

                                      .with(SecurityParts.Password, "test123")

                                      .done().reply();

                            }

                          }

                        });

                 

                This is an implementation of the login client. You can see there's three different CommandTypes which can get signalled to the LoginClient. They are "FailedAuth", "SuccessfulAuth" and "SecurityChallenge".  The fina else block deals with "SecurityChallenge". You can see it just automatically sends a login request to the server -- as it's just an automated test.

                 

                But that's the basic gist of it.

                 

                If that's confusing I can provide additional details. But like I said, proper documentation is forthcoming. =)

                1 of 1 people found this helpful
                • 5. Re: custom errai.authentication_adapter
                  nva

                  Thank you, I think I follow the flow of messages and am getting an idea how to integrate this into an application built on MVP. Correlating with the server side and focusing on username/password type authentication, is it valid to say that:

                   

                  a. FailedAuth will always be returned when the authentication fails, ie. the username and password are incorrect in case of a username/password authentication.

                   

                  In a real-life scenario this basically means that the only scenarion when FailedAuth is expected is when the login page is displayed and the user provided incorrect credentials. The course of action is to display an error message there.

                   

                  b. SuccessfulAuth will always be returned when an authentication challenge has successfully completed.

                   

                  Again, in real-life this means that this only happens when the login screen is displayed, the user has entered the correct credentials in the login screen, clicked the login button and the application can proceed with the protected service/to the protected area.

                   

                  c. SecurityChallenge will always be returned when a protected service is called and no authentication has yet taken place. The course of action for the client is to display a login page and when the user clicks the login button send the credentials with a message as in the example.

                   

                  The entry point into the whole structure is an attempt calling a proteced service and the message flow will trigger the display of the login screen via the SecurityChallenge message (and not via the FailedAuth). Ie. the default place should be something that calls a protected service, which then triggers the login screen.

                   

                  On the server side, the services can be annotated with RequireAuthentication and RequireRoles to protect them. When using Errai RPC, can these be used on the method level? Ie.

                   

                  {code}@Service

                  public class MixedServiceImpl {

                   

                      @RequireAuthentication

                       public String testProtected() {

                          return "protected data";

                       }

                   

                      public String testPublic() {

                           return "public data"}

                      }

                  }{code}

                   

                  Or is the remote interface the right place for this?

                   

                  Without prior authentication, the first call to testProtected will trigger a "SecurityChallenge" and a call to testPublic will trigger nothing. After successful authentication (with authentication token present in the session), subsequent calls to testProtected will trigger nothing.

                   

                  Is this all correct?

                  • 6. Re: custom errai.authentication_adapter
                    juandavidr

                    Hi, thanx, this will work almost beautilfully, but i have some questions.

                     

                    1. Does ERRAI broadcast to all the "LoginClient" the authentication procedures?

                    2. if so, how do i diferentiate from 1 client to another?

                    3. Does this mean i would have to have a "Presenter" wich denotes the login client to handle the authentication procedures?

                    4. If i wish to know if a user is authenticated before sending a message from the server to the client, what should i do?

                     

                     

                    Thanx.

                    • 7. Re: custom errai.authentication_adapter
                      cbrock

                      No. It does not broadcast, the communication is supposed to be conversational: https://docs.jboss.org/author/display/ERRAI/Conversations

                       

                      To figure out if your authenticated or not, you just attempt to send the message. It's based on the theory that you just try to perform the action, and if you require authentication, you're prompted.

                      • 8. Re: custom errai.authentication_adapter
                        nva

                        Hi Juan,

                         

                        on your questions 3. and 4.:

                         

                        3 - I think the answer is yes, you have to have a login presenter that subscribes to the "LoginClient" subject and reveals itself when a SecurityChallenge is received. At least this is how I'm trying to implement it.

                         

                        4 - On the server-side you can read the authentication token from the session. You can see in the

                        org.jboss.errai.persistence.server.security.HibernateAuthenticationAdapter and the

                        org.jboss.errai.bus.server.security.auth.JAASAdapter classes how the token is handled. If you write your own adapter you can also write your own mechanism to mark the user as authenticated. I presume you do need to keep the existing mechanism for the authentication/authorisation annotations to work.

                         

                        On the client side you will have to request the user login status from the server side.

                        • 9. Re: custom errai.authentication_adapter
                          nva

                          Thanks for the help, I've successfully implemented Errai authentication with a custom authentication adapter. Just to record my experience:

                           

                          1. Server side - very straight forward, the org.jboss.errai.persistence.server.security.HibernateAuthenticationAdapter and the org.jboss.errai.bus.server.security.auth.JAASAdapter classes are a great example how things need to be handled.

                           

                          2. Client side - I'm using the GWTP MVP and found this approach useful:

                           

                          a. Subscribe to the SuccessfulAuth and SecurityChallenge events in the application's entry point. This ensures that this subscription happens before anything else can get revealed. I can also save the original place request here and reveal it after successful authentication. When receiving a SecurityChallenge, then the login page is revealed from there.

                           

                          b. Subscribe to the FailedEvent in the login presente. It's just simpler to handle it there than sending client-side events around again.

                           

                          c. When the login button is clicked, send the login credentials with this message:

                           

                          {code:java}

                          MessageBuilder.createMessage("AuthenticationService")

                                                 .command(SecurityCommands.AuthRequest)

                                                 .with(MessageParts.ReplyTo, "LoginClient")

                                                 .with(SecurityParts.Name, getView().getUsername())

                                                 .with(SecurityParts.Password, getView().getPassword())

                                                 .done().sendNowWith(ErraiBus.get());

                          {code}

                           

                          d. To obtain the currently logged in user, the authentication token can be interrogated, which is set up on the server side in the custom authentication adapter. A straight-forward service can handle this.

                          • 10. Re: custom errai.authentication_adapter
                            magick93

                            Hi Mike

                             

                            is there still some documentation on how to implent authentication / authorization coming?

                             

                            I'm pretty new to Errai, so would really appreciate some docs on this.

                             

                            Thanks for any help

                            • 11. Re: custom errai.authentication_adapter
                              cbrock

                              The only reason we have not done so yet, is that we're working on a new API. The existing approach is actually quite awkward, really and dates back to Errai 1.0. Most of our users just use standard HTTP authentication schemes with HttpSession, etc. Which is fine, since Errai allows you to get at all that. But some of our users want to use the integrated authentication, so we're finally going to modernize the API in 3.0.

                               

                              Is there something you need specific help with?

                              • 12. Re: custom errai.authentication_adapter
                                rruss

                                Mike, is there a proposed API somewhere that people could look at?  If anyone wants to participate in the design, how would/should they go about doing so?