4 Replies Latest reply on Oct 8, 2013 7:48 AM by piotr.kozlowski

    Authentication in RESTful application

    piotr.kozlowski

      Hi,

       

      I have two apps, server side is based on java with rest easy and client where I'm using angular js.

       

      I used basic authentication where I generated token in first request and all requests used this token, but since I moved project to Wildfly, and there is no Tomcat this way doesn't work.

       

      My class TokenAuthenticator extends BasicAuthenticator from Catalina;

       

      web.xml has:

       

      <login-config>

              <realm-name>App</realm-name>

          </login-config>

       

          <security-role>

              <role-name>user</role-name>

          </security-role>

       

      and jboss-web.xml:

       

      <jboss-web>

          <security-domain>App</security-domain>

          <valve>

              <class-name>package.TokenAuthenticator</class-name>

          </valve>

          <context-root>/app-server</context-root>

      </jboss-web>


      In my EJB beans I'm using @RolesAllowed annotation to restrict access to resources.


      I read that for now, Wildfly doesn't support valves.


      What is my the best alternative?


      Regards

      Piotr Kozlowski



        • 1. Re: Authentication in RESTful application
          piotr.kozlowski

          Can I use these handlers like I previously used the valves?

          • 2. Re: Authentication in RESTful application
            swd847

            For now you can write a ServletExtension that adds an io.undertow.security.api.AuthenticationMechanism using the io.undertow.servlet.api.DeploymentInfo#addAuthenticationMechanism method.

             

            The way this works is that all authentication mechanisms are iterated, and their authenticate() method is called giving them a chance to authenticate a user. If none are sucessful then their sendChallenge methods are called in turn, allowing them to send information back to the user in order to begin the authentication process.

             

            At some point (hopefully before final) we will allow this to be configured via XML.

            1 of 1 people found this helpful
            • 3. Re: Authentication in RESTful application
              piotr.kozlowski

              I changed my mind and I've implemented form based authentication.

              Unfortunately I still have few problems.

               

              User is authenticated but in first request I got 500 (internal server error).

              After refresh the page, everything is back to normal.

               

              I suppose that problem is because in log in attempt there is no cookie, but I'm not sure.

              Should I report the bug on JIRA or something is wrong with my app?

               

              11:59:39,022 ERROR [io.undertow.request] (default task-2) Servlet request failed HttpServerExchange{ POST /agido-server/j_security_check}: java.lang.NullPointerException

                at io.undertow.servlet.handlers.security.ServletFormAuthenticationMechanism.handleRedirectBack(ServletFormAuthenticationMechanism.java:64) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.FormAuthenticationMechanism.runFormAuth(FormAuthenticationMechanism.java:118) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.FormAuthenticationMechanism.authenticate(FormAuthenticationMechanism.java:81) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:282) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:299) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:269) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:131) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:106) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:99) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:50) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:65) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:70) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:215) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:202) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:69) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:136) [undertow-servlet-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.server.HttpHandlers.executeRootHandler(HttpHandlers.java:36) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:614) [undertow-core-1.0.0.Beta16.jar:1.0.0.Beta16]

                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_40]

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_40]

                at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_40]

               

              In ServletFormAuthenticationMechanism class, there is a for loop which iterates through cookies array, but what if a cookies are null?

              • 4. Re: Authentication in RESTful application
                piotr.kozlowski

                For previously (empty cookies problem) I found workaround and reported issue [UNDERTOW-110] NPE in ServletFormAuthenticationMechanism caused by empty cookies variable - JBoss Issue Tracker.

                In my ExceptionHandler, when I got 401, I'm starting new session using httpServletRequest.getSession(true).

                 

                Besides, I have few more questions.

                 

                1. In ServletFormAuthenticationMechanism class, handleRedirectBack() method, there is a if statement which try to find LOCATION_COOKIE ("FORM_AUTH_ORIGINAL_URL") and otherwise throws RuntimeException. So I'm forced to create this cookie with requested url before authentication? This is only way?

                 

                2. I'm using @RolesAllowed(Roles.USER) annotations to secure my EJB's, before (when I'm deploying my app on AS7) annotations on interfaces works fine, but now on Wildfly only works when I've put this annotations in implementation. Why?

                 

                3. Another question related with @RolesAllowed annotation.

                In REST I'm invoking method from Class1, which invokes another method from Class2, which invokes another method from Class3 etc. and I was forced to put annotations @RolesAllowed(Roles.USER) everywhere until I set default behavior as permit all by using:

                    <s:missing-method-permissions-deny-access>false</s:missing-method-permissions-deny-access>

                Is it normal behavior?

                 

                My jboss-ejb3.xml looks like below:

                 

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

                <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:s="urn:security:1.1" version="3.1"

                               impl-version="2.0">

                    <assembly-descriptor xmlns="http://java.sun.com/xml/ns/javaee">

                        <s:security>

                            <s:security-domain>Agido</s:security-domain>

                            <ejb-name>*</ejb-name>

                            <s:missing-method-permissions-deny-access>false</s:missing-method-permissions-deny-access>

                        </s:security>

                    </assembly-descriptor>

                </jboss:ejb-jar>

                 

                 

                Thanks for answers.

                 

                Best regards

                Piotr Kozlowski