sparkjava Authentication

5,439 views
Skip to first unread message

Salai Sivamal

unread,
Apr 27, 2015, 1:15:29 PM4/27/15
to spar...@googlegroups.com
Experts please advise...!!

I really like the way sparkjava written, I am a long time java programmers, trying to use sparkjava for my new application.
However I stuck with providing Authentication for sparkjava, tried Shiro, it needs ServletContext to initialize, so did not work, for me at least.

Serious of random questions;
1. How do I leverage Jetty security constraints to provide Authentication? It needs WebAppContext, how do I get this?
2. The application start with spark.Spark, provides the before, after filters, other than that is there anyway I can leverage running Jetty within?
3. How I trigger Basic Authentication dialog for the user? Is there anything I miss understood the way sparkjava meant to be used.... :o(

Please share anything you want to say about my Authentication requirement, all I am looking is Basic Authentication with sparkjava(without Tomcat)...

I would appreciate any kind of input on this...

Thanks,
Salai



Christian MICHON

unread,
Apr 28, 2015, 2:18:08 AM4/28/15
to spar...@googlegroups.com
Spark encapsulates jetty completely, so it might be difficult to retrieve the jetty server instance itself, and therefore all sub instances (connectors, context handlers, etc...).

Yet you could implement a token based authentication (json web token sent in the headers) using a simple 'before' spark filter. Then you would not need Shiro and access to ServletContext.

Salai Sivamal

unread,
Apr 28, 2015, 9:55:15 AM4/28/15
to spar...@googlegroups.com
Great! I am going to try that. Let me clarify my basic understanding, can jwt be used still for username and password auth? I don't want API Key kind implementation, my need here is user/password with SSL, user friendlessness.

Btw, I tried Basic Auth, setting 401 status with "WWW-Authenticate: Basic realm=myRealm" in the header to prompt Authentication dialog, it did not work, may be because, Response class masks HTTPServletResponse.

Would be nice, if the Security and Authentication parts documented in the sparkjava.com. Ohh...Is that reason Tomcat mix used ???

Anyway, I post my progress here....

-Sal

Salai Sivamal

unread,
Apr 28, 2015, 10:03:21 AM4/28/15
to spar...@googlegroups.com
Thanks!
I am going to try



On Monday, April 27, 2015 at 12:15:29 PM UTC-5, Salai Sivamal wrote:

Christian MICHON

unread,
Apr 28, 2015, 5:17:45 PM4/28/15
to spar...@googlegroups.com
jwt is used to encapsulate the session information of a verified authentication, and whatever you wish to include inside the token.

I usually include at least the user id and until when the token is valid.

Username/Password you could leave it to shiro-core. For your SSL concerns, it'll work but keep in mind to put Spark in secure mode and to give it a keystore with the SSL certificates.

So auth0/java-jwt + shiro-core + Spark in secure mode should work out for you.

If you need more specific help, please put your code in github.

Salai Sivamal

unread,
May 22, 2015, 12:39:26 AM5/22/15
to spar...@googlegroups.com
I have a simple program written, 2 pages.
1. Authentication page
2. Secured index page

I am able to authenticate and generate the token, I am bit lost in using the 'after' filter to set the Bearer token.

My questions as follow:
1. In /auth post, how to set the token in the response header? After setting token I am trying to redirect to another page, is that correct?
2. What is expected return statement in (line 92) for?
  
https://github.com/gsivamal/spark-java1

Your feedback/corrects greatly appreciated.

Christian MICHON

unread,
May 22, 2015, 5:51:16 PM5/22/15
to spar...@googlegroups.com
This is how I do it with Spark + auth0 jwt. Please bear with me as it is not 100% java but Nashorn javascript (for java8)...

I've a function to handle post to /authenticate, and this returns a JSON output. The client is supposed to grab this output and store it into local storage.

_post('authenticate', function (req,res) {
  var username = req.queryParams('username');
  var password = req.queryParams('password');
  var authenticated, out;
  if (username && password) {
    authenticated = _authenticate(username, password);
    if (authenticated) {
      out = { success: authenticated, token: _create_jwt(username) };
    } else {
      out = { success: false, reason: 'Wrong credentials' };
    }
  } else {
    _halt(401);
  }
  res.type("application/json");
  return JSON.stringify(out);
});

Here are the underlying functions:

    Object.prototype._authenticate = function (username, password) {
      var authenticated;
      try {
        var cu = SecurityUtils.getSubject();
        var cs = cu.getSession();
        cu.login(new UsernamePasswordToken(username, password));
        authenticated = cu.isAuthenticated();
        cu.logout();
      }
      catch(e) {
        authenticated = false;
      }
      finally {
        return authenticated;
      }
    }

and jwt related functions:

var _SECRET = '$3CR37';
    var _EXPIRY = 12 * 3600 * 1000;

    Object.prototype._create_jwt = function (username) {
      var jwt;
      var token = new HashMap();
      token.uid = username;
      token.role = 1;
      token.exp = (new Date()).getTime() + _EXPIRY;
      try {
        var signer = new JWTSigner(_SECRET);
        jwt = signer.sign(token);
      }
      catch(e) {
        // undefined as default value
      }
      finally {
        return jwt;
      }
    }

    Object.prototype._verify_jwt = function (jwt) {
      var verification;
      try {
        var verifier = new JWTVerifier(_SECRET);
        verification = verifier.verify(jwt);
        // 3 possible invalidations of token
        if (!(verification.exp >= new Date())) { verification = undefined; }
        if (verification.uid === null) { verification = undefined; }
        if (verification.role === null) { verification = undefined; }
      }
      catch(e) {
        // undefined as default value
      }
      finally {
        return verification;
      }
    }

Now my application is a single web page application: if I get a status 401, the client pops back the login dialog, I've no redirection...

The client will send the auth token inside the header. It's not related to a 'after' filter.

_before('data/*', function (req,res) {
  var jwt = req.headers('authorization');
  if (jwt) {
    if (_verify_jwt(jwt) !== undefined) {
      // PASS 200
    } else {
      _halt(401);
    }
  } else {
    _halt(401);
  }
});

I used ExtJS for the client. I need to port this server code to java if you wish to use it, and I'm in the process of writing a small angular client code as well.

Next week at best...

Salai Sivamal

unread,
Jun 3, 2015, 3:30:55 PM6/3/15
to spar...@googlegroups.com
I also trying to port into java8, Thank you!

1. The code explained here is very clear, except one thing, what is the purpose of Shiro? if Shiro can do Session-Cookie Authentication, jwt is to provide additional security?
I was always thinking, either Token based or Session based authentication. Am I missing something....

Salai Sivamal

unread,
Jun 3, 2015, 4:21:05 PM6/3/15
to spar...@googlegroups.com
I also trying to port into java8, Thanks!
 
1. The code explained here is very clear, except one thing, what is the purpose of Shiro? if Shiro can do Session-Cookie Authentication, jwt is to provide additional security?
I was always thinking, either Token based or Session based authentication. Am I missing something....
 
2. I am curious to see, the flow after authentication success.
When somebody punches, 'http://appname/' or 'http://appname/login' pop a login dialog.
User/browser posts the credentials to 'authenticate', after success, how does he land in a Dashboard page(I have template for dashboard.ftl). ?

Any kind of input is welcome...

Christian MICHON

unread,
Jun 3, 2015, 6:23:36 PM6/3/15
to spar...@googlegroups.com
Shiro purpose is to help authenticate only. Jwt create then a trusted token with signature and send it to the client. The js client must send this token for each xhr request otherwise the request is denied and the client must reauthenticate.

Advantage of token vs session: the server does not store anything anymore, the client stores the needed information. Downside is that the server must check validity of jwt token for each request, yet it's still faster than looking for a session Id in the database.

Christian MICHON

unread,
Jun 3, 2015, 6:26:42 PM6/3/15
to spar...@googlegroups.com
In a single page webapp you need to handle this on client side not on server. You could otherwise perform a redirect after jwt emission, but this could jeopardize the local storage of the jwt token.

Is your application a SPA?

Salai Sivamal

unread,
Jun 3, 2015, 10:38:45 PM6/3/15
to spar...@googlegroups.com
Yes, it is going to be SPA, planning to use.
http://192.241.236.31/themes/preview/smartadmin/1.5/ajaxversion/#ajax/dashboard.html

SPA kicks in once Authentication success, means I want to load the Menus based on the user role. Any thoughts on this....

Thanks,

Gustavo Galvan

unread,
Jun 5, 2015, 12:53:42 PM6/5/15
to spar...@googlegroups.com
A very simple basic auth using a filter.... (user: admin, pass: admin)

before("/*", (request, response) -> {
Boolean authenticated = false;
String auth = request.headers("Authorization");
if(auth != null && auth.startsWith("Basic")) {
String b64Credentials = auth.substring("Basic".length()).trim();
String credentials = new String(Base64.getDecoder().decode(b64Credentials));
System.out.println(credentials);
if(credentials.equals("admin:admin")) authenticated = true;
}
if(!authenticated) {
response.header("WWW-Authenticate", "Basic realm=\"Restricted\"");
response.status(401);
}
});
Reply all
Reply to author
Forward
0 new messages