4

I have a webapp which has angularJS on the frontend and Java on the backed. Angular communicates with the java backend via Restful webservices consuming and sending JSON across HTTP. I need to build the authentication mechanism for this app and was wondering how would be the best approach, currently I'm using JAAS based authentication (JDBC user table). This is how my app is configured:

My web.xml configuration has:

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>userauth</realm-name>
        <form-login-config>
            <form-login-page>/login.html</form-login-page>
            <form-error-page>/loginError.html</form-error-page>
        </form-login-config>                
    </login-config>

    <security-constraint>   
        <display-name>ConstraintSSL</display-name>
        <web-resource-collection>
            <web-resource-name>protected</web-resource-name>
            <description/>
            <url-pattern>/checkout/*</url-pattern>
            <url-pattern>/login/*</url-pattern>
            <url-pattern>/login.*</url-pattern>
            <url-pattern>/account/*</url-pattern>
            <url-pattern>/ad/create</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>HEAD</http-method>
            <http-method>PUT</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>

        <user-data-constraint>        
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>        
    </security-constraint>

    <security-constraint>   
        <display-name>ConstraintUser</display-name>
        <web-resource-collection>
            <web-resource-name>user</web-resource-name>
            <description/>
            <url-pattern>/account/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>HEAD</http-method>
            <http-method>PUT</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <auth-constraint>       
            <description/>
            <role-name>ADMINISTRATORS</role-name>
            <role-name>USERS</role-name>
        </auth-constraint>

        <user-data-constraint>        
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>        
    </security-constraint>

    <security-role>
        <description/>
        <role-name>USERS</role-name>
    </security-role>
    <security-role>
        <description/>
        <role-name>ADMINISTRATORS</role-name>
    </security-role>

  <session-config>
    <session-timeout>30</session-timeout>
    <tracking-mode>COOKIE</tracking-mode>
  </session-config>

   <welcome-file-list>
    <welcome-file>init.html</welcome-file>
   </welcome-file-list>

init.html only redirects to a index.html page which loads angular and starts the actual app.

Now here is my UserController which handles user related activities on the client side (browser):

myControllers.controller('UserController', ['$scope', '$routeParams', 'UserService',
  function($scope, $routeParams, UserService) {
    $scope.logged = false;

    // if User is not detected by cookie
    $scope.user = fetchUserFromCookie();

    if (! $scope.user) {

        // set default guest user
        $scope.user = {         
            firstName : 'guest',
            lastName : 'user',
            preferredCurrency : "USD$",
            sessionHash: "XXXXXX",
            shoppingCart : {
                totalItems : 0,
                total : 0
            }           
        };      

    }

    $scope.login = function(userName, pass) {
          $scope.user = UserService.login(userName, pass);            
          $scope.logged = true;      
    };

    $scope.logout = function(userName) {
          $scope.user = UserService.logout(userName); // warn server side you're logging out
          $scope.logged = false;
          $scope.user = null;
    };

  }]);

My goal is to provide a login page with JAAS based JDBC authentication, and to allow only those user which has a specific ADMIN role or USER role to see a certain page, how to achieve this in a angularJS + Java based app ?

  • my main concerns are with session tracking,

  • how to track that a specific user has granted access and has permissions to change a specific record ?

  • how to prevent manual hacks like manually changing JS code or changing a Cookie in order to hijack a user session ?

guilhebl
  • 8,330
  • 10
  • 47
  • 66
  • Always do server-side permission checks and you won't have problem#3! – madhead Jun 09 '14 at 22:16
  • yes but how to achieve that? How can I know the actual client calling the REST endpoint is a specific authorized user? Should I pass tokens around the client and server for the duration of the Session? Can you point to a sample implementation ? Thanks – guilhebl Jun 10 '14 at 23:15
  • 1
    I have a simlar issue and found the post http://www.aschua.de/blog/pairing-angularjs-and-javaee-for-authentication/. Maybe this helps you, too, even it is a little late. – Rick-Rainer Ludwig Sep 28 '14 at 20:56
  • Thanks! It definitely helps – guilhebl Sep 29 '14 at 17:37
  • @guilhebl From where are you fetching the role details of user? From database or from Web.xml file? Could you please help. I am at same stage implementing authentication using angular+java – kittu Jan 19 '16 at 13:27
  • @guilhebl I am using plain java class like DAO etc for authentication. How is JAAS authentication? Is at good to have? – kittu Jan 19 '16 at 13:28
  • @Satyadev you can use programmatic login with DAO etc, or else some other approach such as container managed login (JAAS), one benefit of the latter is that it saves you some time since you don't have to write boilerplate code for your login flow, the application server will handle the login for you through JAAS, example: http://guilhebl.github.io/java/2014/04/01/creating-jaas-auth-realm-glassfish/ – guilhebl Jan 19 '16 at 19:59

1 Answers1

0
  • index.html page should contain token inside html to avoid CSRF
  • token shouldn't be stored in a cookie storage
  • Each request should be signed with header param
  • Server should validate every request by passed header
  • If cookie usage is a must you should validate referer in order to prevent CSRF
nesteant
  • 1,070
  • 9
  • 16
  • you mean place the cookie in the HTML as a hidden field? Also I have the requirement of remembering the user even if he closes the browser then I'm saving the token in the cookie and also in the server-side, so later on I can restore the user's session without having him login again, is there any risk on doing this ? – guilhebl May 25 '15 at 22:36
  • I mean smth like div with token attribute. If you need to store token you should use local storage instead of cookies if possible (ie9+). If you still need to use cookies try to read more about csrf. http://en.wikipedia.org/wiki/Cross-site_request_forgery The most easy way I remember to check referer and token on the server side – nesteant May 26 '15 at 04:57
  • I see but I want to enable the "remember me" feature just like stack exchange or other sites do, when user closes his browser and opens again I want to restore his session, the only problem using LocalStorage is that since its an HTML5 feature old browsers don't support it, so I'm using Cookies in this case, so I'll have to make sure I validate referer. – guilhebl May 26 '15 at 06:53