{"id":58652,"date":"2016-07-25T12:10:57","date_gmt":"2016-07-25T09:10:57","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=58652"},"modified":"2016-08-01T23:48:02","modified_gmt":"2016-08-01T20:48:02","slug":"token-authentication-java-applications","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html","title":{"rendered":"Token Authentication for Java Applications"},"content":{"rendered":"<p><span style=\"font-size: 20px;\">Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and <a href=\"https:\/\/docs.stormpath.com\/java\/?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_term=cta&#038;utm_content=token-auth-for-java&#038;utm_campaign=java-2016\">robust Java SDK support<\/a> can eliminate your security risk and can be implemented in minutes. <a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_term=cta&#038;utm_content=token-auth-for-java&#038;utm_campaign=java-2016\">Sign up<\/a>, and never build auth again!<\/span><\/p>\n<p><strong>Update 5\/12\/2016:<\/strong> Building a Java application? <a href=\"https:\/\/stormpath.com\/blog\/jjwt-how-it-works-why\/?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_term=cta&#038;utm_content=token-auth-for-java&#038;utm_campaign=java-2016\">JJWT<\/a> is a Java library providing end-to-end JWT creation and verification, developed by our very own Les Hazlewood. Forever free and open-source (Apache License, Version 2.0), JJWT is simple to use and understand. It was designed with a builder-focused fluent interface hiding most of its complexity. We\u2019d love to have you <a href=\"https:\/\/github.com\/jwtk\/jjwt\">try it out<\/a>, and let us know what you think! (And, if you\u2019re a Node developer, check out <a href=\"https:\/\/github.com\/jwtk\/njwt\">NJWT<\/a>!)<\/p>\n<p>In my <a href=\"https:\/\/stormpath.com\/blog\/secure-single-page-app-problem?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">last post<\/a>, we covered a lot of ground, including how we traditionally go about securing websites, some of the pitfalls of using cookies and sessions, and how to address those pitfalls by traditional means.<\/p>\n<p>In this post we\u2019ll go beyond the traditional and take a deep dive into how token authentication with JWTs (JSON Web Tokens) not only addresses these concerns, but also gives us the benefit of inspectable meta-data and strong cryptographic signatures.<\/p>\n<h2>Token Authentication to the Rescue!<\/h2>\n<p>Let\u2019s first examine what we mean by <code>authentication<\/code> and <code>token<\/code> in this context.<\/p>\n<p>Authentication is proving that a user is who they say they are.<\/p>\n<p>A token is a self-contained singular chunk of information. It could have intrinsic value or not. We are going to look at a particular type of token that <em>does<\/em> have intrinsic value and addresses a number of the concerns with session IDs.<\/p>\n<h3>JSON Web Tokens (JWTs)<\/h3>\n<p>JWTs are a URL-safe, compact, self-contained string with meaningful information that is usually digitally signed or encrypted. They\u2019re quickly becoming a de-facto standard for token implementations across the web.<\/p>\n<p>URL-safe is a fancy way of saying that the entire string is encoded so there are no special characters and the token can fit in a URL.<\/p>\n<p>The string is opaque and can be used standalone in much the same way that session IDs are used. By opaque, I mean that looking at the string itself provides no additional information.<\/p>\n<p>However, the string can also be decoded to pull out-meta data and it\u2019s signature can be cryptographically verified so that your application knows that the token has not been tampered with.<\/p>\n<h4>JWTs and OAuth2 Access Tokens<\/h4>\n<p>Many OAuth2 implementations are using JWTs for their access tokens. It should be stated that the OAuth2 and JWT specifications are completely separate from each other and don\u2019t have any dependencies on each other. Using JWTs as the token mechanism for OAuth2 affords a lot of benefit as we\u2019ll see below.<\/p>\n<p>JWTs can be stored in cookies, but all the rules for cookies we discussed <a href=\"https:\/\/stormpath.com\/blog\/secure-single-page-app-problem?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">before<\/a> still apply. You can entirely replace your session id with a JWT. You can then gain the additional benefit of accessing the meta-information directly from that session id.<\/p>\n<p>In the wild, they look like just another ugly string:<\/p>\n<pre class=\"brush:bash; wrap-lines:false\">eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vdHJ1c3R5YXBwLmNvbS8iLCJleHAiOjEzMDA4MTkzODAsInN1YiI6InVzZXJzLzg5ODM0NjIiLCJzY29wZSI6InNlbGYgYXBpL2J1eSJ9.43DXvhrwMGeLLlP4P4izjgsBB2yrpo82oiUPhADakLs<\/pre>\n<p>If you look carefully, you can see that there are two periods in the string. These are significant as they delimit different sections of the JWT.<\/p>\n<pre class=\"brush:bash; wrap-lines:false\">eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\r\n.\r\neyJpc3MiOiJodHRwOi8vdHJ1c3R5YXBwLmNvbS8iLCJleHAiOjEzMDA4MTkzODAsInN1YiI6InVzZXJzLzg5ODM0NjIiLCJzY29wZSI6InNlbGYgYXBpL2J1eSJ9\r\n.\r\n43DXvhrwMGeLLlP4P4izjgsBB2yrpo82oiUPhADakLs<\/pre>\n<h4>JWT Structure<\/h4>\n<p>JWTs have a three part structure, each of which is base64-encoded:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/07\/jwt_parts.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-58654\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/07\/jwt_parts.png\" alt=\"jwt_parts\" width=\"805\" height=\"350\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/07\/jwt_parts.png 805w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/07\/jwt_parts-300x130.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/07\/jwt_parts-768x334.png 768w\" sizes=\"(max-width: 805px) 100vw, 805px\" \/><\/a><\/p>\n<p>Here are the parts decoded:<\/p>\n<p><strong>Header<\/strong><\/p>\n<pre class=\"brush:bash\">{\r\n  \"typ\": \"JWT\",\r\n  \"alg\": \"HS256\"\r\n}<\/pre>\n<p><strong>Claims<\/strong><\/p>\n<pre class=\"brush:bash\">{\r\n  \"iss\":\"http:\/\/trustyapp.com\/\",\r\n  \"exp\": 1300819380,\r\n  \"sub\": \"users\/8983462\",\r\n  \"scope\": \"self api\/buy\"\r\n}<\/pre>\n<p><strong>Cryptographic Signature<\/strong><\/p>\n<pre class=\"brush:bash\">t\u00df\u00b4\u2014\u2122\u00e0%O\u02dcv+n\u00ee\u2026SZu\u00af\u00b5\u20acU\u20268H\u00d7<\/pre>\n<h4>JWT Claims<\/h4>\n<p>Let\u2019s examine the claims sections. Each type of claim that is part of the JWT Specification can be found <a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-oauth-json-web-token-32\">here<\/a>.<\/p>\n<p><code>iss<\/code> is who issued the token.<br \/>\n<code>exp<\/code> is when the token expires.<br \/>\n<code>sub<\/code> is the subject of the token. This is usually a user identifier of some sort.<\/p>\n<p>The above parts of the claim are all included in the JWT specification. <code>scope<\/code> is not included in the specification, but it is commonly used to provide authorization information. That is, what parts of the application the user has access to.<\/p>\n<p>One advantage of JWTs is that arbitrary data can be encoded into the claims as with <code>scope<\/code> above. Another advantage is that the client can now react to this information without any further interaction with the server. For instance, a portion of the page may be hidden based on the data found in the<code>scope<\/code> claim.<\/p>\n<p><strong>NOTE<\/strong>: It is still critical and a best practice for the server to always verify actions taken by the client. If, for instance, some administrative action was being taken on the client, you would still want to verify on the application server that the current user had permission to perform that action. You would never rely on client side authorization information alone.<\/p>\n<p>You may have picked up on another advantage: the cryptographic signature. The signature can be verified which proves that the JWT has not been tampered with. Note that the presence of a crytpographic signature does not guarantee confidentiality. Confidentiality is ensured only when the JWT is encrypted <em>as well as<\/em> signed.<\/p>\n<p>Now, for the big kicker: <strong>statelessness<\/strong>. While the server will need to generate the JWT, it does not need to store it anywhere as all of the user meta-data is encoded right in to the JWT. The server and client could pass the JWT back and forth and never store it. This scales very well.<\/p>\n<h3>Managing Bearer Token Security<\/h3>\n<p>Implicit trust is a tradeoff. These types of tokens are often referred to as Bearer Tokens because all that is required to gain access to the protected sections of an application is the presentation of a valid, unexpired token.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>You have to address issues like: How long should the token be good for? How will you revoke it? (There\u2019s a whole other post we could do on <a href=\"http:\/\/tools.ietf.org\/html\/rfc6749#section-1.5\">refresh tokens<\/a>.)<\/p>\n<p>You have to be mindful of what you store in the JWT if they are not encrypted. Do <em>not<\/em> store any sensitive information. It is generally accepted practice to store a user identifier in the form of the <code>sub<\/code>claim. When a JWT is signed, it\u2019s referred to as a JWS. When it\u2019s encrypted, it\u2019s referred to as a JWE.<\/p>\n<h3>Java, JWT and You!<\/h3>\n<p>We are very proud of the <a href=\"https:\/\/github.com\/jwtk\/jjwt\">JJWT<\/a> project on Github. Primarily authored by Stormpath\u2019s own CTO, <a href=\"https:\/\/github.com\/lhazlewood\">Les Hazlewood<\/a>, it\u2019s a fully open-source JWT solution for Java. It\u2019s the easiest to use and understand library for creating and verifying JSON Web Tokens on the JVM.<\/p>\n<p>How do you create a JWT? Easy peasy!<\/p>\n<pre class=\"brush:java\">import io.jsonwebtoken.Jwts;\r\nimport io.jsonwebtoken.SignatureAlgorithm;\r\n \r\nbyte[] key = getSignatureKey();\r\n \r\nString jwt = \r\n    Jwts.builder().setIssuer(\"http:\/\/trustyapp.com\/\")\r\n        .setSubject(\"users\/1300819380\")\r\n        .setExpiration(expirationDate)\r\n        .put(\"scope\", \"self api\/buy\") \r\n        .signWith(SignatureAlgorithm.HS256,key)\r\n        .compact();<\/pre>\n<p>The first thing to notice is the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fluent_interface\">fluent<\/a> builder api used to create a JWT. Method calls are chained culminating in the <code>compact<\/code> call which returns the final JWT string.<\/p>\n<p>Also notice that when we are setting one of the claims from the specification, we use a setter. For example: <code>.setSubject(\"users\/1300819380\")<\/code>. When a custom claim is set, we use a call to put and specify both the key and value. For example: <code>.put(\"scope\", \"self api\/buy\")<\/code><\/p>\n<p>It\u2019s just as easy to verify a JWT.<\/p>\n<pre class=\"brush:java\">String subject = \"HACKER\";\r\ntry {\r\n    Jws jwtClaims = \r\n        Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);\r\n \r\n    subject = claims.getBody().getSubject();\r\n \r\n    \/\/OK, we can trust this JWT\r\n \r\n} catch (SignatureException e) {\r\n \r\n    \/\/don't trust the JWT!\r\n}<\/pre>\n<p>If the JWT has been tampered with in any way, parsing the claims will throw a <code>SignatureException<\/code>and the value of the <code>subject<\/code> variable will stay <code>HACKER<\/code>. If it\u2019s a valid JWT, then <code>subject<\/code> will be extracted from it: <code>claims.getBody().getSubject()<\/code><\/p>\n<h3>What is OAuth?<\/h3>\n<p>In the next section, we\u2019ll look at an example using Stormpath\u2019s OAuth2 implementation, which makes use of JWTs.<\/p>\n<p>There\u2019s a lot of confusion around the OAuth2 spec. That\u2019s, in part, because it is really an \u00fcber spec \u2013 it has a lot of complexity. It\u2019s also because OAuth1.a and OAuth2 are very different beasts. We are going to look at a very specific, easy to use, subset of the OAuth2 spec. We have an excellent post that goes into much more detail on <a href=\"https:\/\/stormpath.com\/blog\/what-the-heck-is-oauth?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">What the Heck is OAuth<\/a>. Here, we\u2019ll give some brief background and then jump right into the examples.<\/p>\n<p>OAuth2 is basically a protocol that supports <strong>authorization workflows<\/strong>. What this means is that it gives you a way to ensure that a specific user has permissions to do something.<\/p>\n<p>That\u2019s it.<\/p>\n<p>OAuth2 <em>isn\u2019t<\/em> meant to do stuff like validate a user\u2019s identity \u2014 that\u2019s taken care of by an Authentication service. Authentication is when you validate a user\u2019s identity (<em>like asking for a username \/ password to log in<\/em>), whereas authorization is when you check to see what permissions an existing user already has.<\/p>\n<p>Just remember that OAuth2 is a protocol for <em>authorization<\/em>.<\/p>\n<h4>Using OAuth Grant Types for Authorization<\/h4>\n<p>Let\u2019s look at a typical OAuth2 interaction.<\/p>\n<pre class=\"brush:bash\">POST \/oauth\/token HTTP\/1.1\r\nOrigin: https:\/\/foo.com\r\nContent-Type: application\/x-www-form-urlencoded\r\n \r\ngrant_type=password&amp;amp;username=username&amp;amp;password=password<\/pre>\n<p><code>grant_type<\/code> is required. The <code>application\/x-www-form-urlencoded<\/code> content type is required for this type of interaction as well. Given that you are passing the username and password over the wire, you would <em>always<\/em> want the connection to be secure. The good thing, however, is that the response will have an OAuth2 bearer token. This token will then be used for every interaction between the browser and server going forward. There is a very brief exposure here where the username and password are passed over the wire. Assuming the authentication service on the server verifies the username and password, here\u2019s the response:<\/p>\n<pre class=\"brush:bash\">HTTP\/1.1 200 OK\r\nContent-Type: application\/json;charset=UTF-8\r\nCache-Control: no-store\r\nPragma: no-cache\r\n \r\n{\r\n    \"access_token\":\"2YotnFZFEjr1zCsicMWpAA...\",\r\n    \"token_type\":\"example\",\r\n    \"expires_in\":3600,\r\n    \"refresh_token\":\"tGzv3JOkF0XG5Qx2TlKWIA...\",\r\n    \"example_parameter\":\"example_value\"\r\n}<\/pre>\n<p>Notice the <code>Cache-Control<\/code> and <code>Pragma<\/code> headers. We don\u2019t want this response being cached anywhere. The <code>access_token<\/code> is what will be used by the browser in subsequent requests. Again, there is not direct relationship between OAuth2 and JWT. However, the <code>access_token<\/code> can be a JWT. That\u2019s where the extra benefit of the encoded meta-data comes in. Here\u2019s how the access token is leveraged in future requests:<\/p>\n<pre class=\"brush:bash\">GET \/admin HTTP\/1.1\r\nAuthorization: Bearer 2YotnFZFEjr1zCsicMW...<\/pre>\n<p>The <code>Authorization<\/code> header is a standard header. No custom headers are required to use OAuth2. Rather than the type being <code>Basic<\/code>, in this case the type is <code>Bearer<\/code>. The access token is included directly after the <code>Bearer<\/code> keyword. This completes the OAuth2 interaction for the password grant type. Every subsequent request from the browser can use the <code>Authorizaion: Bearer<\/code> header with the access token.<\/p>\n<p>There\u2019s another grant type known as <code>client_credentials<\/code> which uses <code>client_id<\/code> and<code>client_secret<\/code>, rather than <code>username<\/code> and <code>password<\/code>. This grant type is typically used for API interactions. While the client id and slient secret function similarly to a username and password, they are usually of a higher quality security and not necessarily human readable.<\/p>\n<h2>Take Us Home: OAuth2 Java Example<\/h2>\n<p>We\u2019ve arrived! It\u2019s time to dig into some specific code that demonstrates JWTs in action.<\/p>\n<h3>Spring Boot Web MVC<\/h3>\n<p>There are a number of examples in the <a href=\"https:\/\/github.com\/stormpath\/stormpath-sdk-java\">Stormpath Java SDK<\/a>. Here, we are going to look at a Spring Boot Web MVC example. Here\u2019s the <a href=\"https:\/\/github.com\/stormpath\/stormpath-sdk-java\/blob\/master\/examples\/spring-boot-webmvc\/src\/main\/java\/tutorial\/HelloController.java\">HelloController<\/a> from the example:<\/p>\n<pre class=\"brush:java\">@RestController\r\npublic class HelloController {\r\n \r\n    @RequestMapping(\"\/\")\r\n    String home(HttpServletRequest request) {\r\n \r\n        String name = \"World\";\r\n \r\n        Account account = AccountResolver.INSTANCE.getAccount(request);\r\n        if (account != null) {\r\n            name = account.getGivenName();\r\n        }\r\n \r\n        return \"Hello \" + name + \"!\";\r\n    }\r\n \r\n}<\/pre>\n<p>The key line, for the purposes of this demonstration is:<\/p>\n<p><code>Account account = AccountResolver.INSTANCE.getAccount(request);<\/code><\/p>\n<p>Behind the scenes, <code>account<\/code> will resolve to an <code>Account<\/code> object (and not be <code>null<\/code>) ONLY if an authenticated session is present.<\/p>\n<h3>Build and Run the Example Code<\/h3>\n<p>To build and run this example, do the following:<\/p>\n<pre class=\"brush:bash\">\u263a dogeared jobs:0 ~\/Projects\/StormPath\/stormpath-sdk-java (master|8100m)\r\n\u27a5 cd examples\/spring-boot-webmvc\/\r\n\u263a dogeared jobs:0 ~\/Projects\/StormPath\/stormpath-sdk-java\/examples\/spring-boot-webmvc (master|8100m)\r\n\u27a5 mvn clean package\r\n[INFO] Scanning for projects...\r\n[INFO]\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Building Stormpath Java SDK :: Examples :: Spring Boot Webapp 1.0.RC4.6-SNAPSHOT\r\n[INFO] ------------------------------------------------------------------------\r\n \r\n... skipped output ...\r\n \r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] BUILD SUCCESS\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Total time: 4.865 s\r\n[INFO] Finished at: 2015-08-04T11:46:05-04:00\r\n[INFO] Final Memory: 31M\/224M\r\n[INFO] ------------------------------------------------------------------------\r\n\u263a dogeared jobs:0 ~\/Projects\/StormPath\/stormpath-sdk-java\/examples\/spring-boot-webmvc (master|8100m<\/pre>\n<h3>Launch the Spring Boot Example<\/h3>\n<p>You can then launch the Spring Boot example like so:<\/p>\n<pre class=\"brush:bash; wrap-lines:false\">\u263a dogeared jobs:0 ~\/Projects\/StormPath\/stormpath-sdk-java\/examples\/spring-boot-webmvc (master|8104m)\r\n\u27a5 java -jar target\/stormpath-sdk-examples-spring-boot-web-1.0.RC4.6-SNAPSHOT.jar\r\n \r\n  .   ____          _            __ _ _\r\n \/\\\\ \/ ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\r\n( ( )\\___ | '_ | '_| | '_ \\\/ _` | \\ \\ \\ \\\r\n \\\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\r\n  '  |____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/\r\n =========|_|==============|___\/=\/_\/_\/_\/\r\n :: Spring Boot ::        (v1.2.1.RELEASE)\r\n \r\n2015-08-04 11:51:00.127  INFO 17973 --- [           main] tutorial.Application                     : Starting Application v1.0.RC4.6-SNAPSHOT on MacBook-Pro.local with PID 17973 \r\n \r\n... skipped output ...\r\n \r\n2015-08-04 11:51:04.558  INFO 17973 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)\r\n2015-08-04 11:51:04.559  INFO 17973 --- [           main] tutorial.Application                     : Started Application in 4.599 seconds (JVM running for 5.103)<\/pre>\n<p><strong>NOTE<\/strong>: This assumes that you\u2019ve already setup a Stormpath account and that your api keys are located in <code>~\/.stormpath\/apiKey.properties<\/code>. Look <a href=\"http:\/\/docs.stormpath.com\/java\/spring-boot-web\/quickstart.html?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">here<\/a> for more information on quick setup up of Stormpath with Spring Boot.<\/p>\n<h3>Authenticate with a JSON Web Token (or Not)<\/h3>\n<p>Now, we can exercise the example and show some JWTs in action! First, hit your endpoint without any authentication. I like to use <a href=\"https:\/\/github.com\/jkbrzt\/httpie\">httpie<\/a>, but any command line http client will do.<\/p>\n<pre class=\"brush:bash\">\u27a5 http -v localhost:8080\r\nGET \/ HTTP\/1.1\r\nAccept: *\/*\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\nHost: localhost:8080\r\nUser-Agent: HTTPie\/0.9.2\r\n \r\n \r\nHTTP\/1.1 200 OK\r\nAccept-Charset: big5, big5-hkscs, cesu-8, euc-jp, euc-kr, gb18030, ... \r\nContent-Length: 12\r\nContent-Type: text\/plain;charset=UTF-8\r\nDate: Tue, 04 Aug 2015 15:56:41 GMT\r\nServer: Apache-Coyote\/1.1\r\n \r\nHello World!<\/pre>\n<p>The <code>-v<\/code> parameter produces verbose output and shows all the headers for the request and the response. In this case, the output message is simply: <code>Hello World!<\/code>. This is because there is not an established session.<\/p>\n<h4>Authenticate with the Stormpath OAuth Endpoint<\/h4>\n<p>Now, let\u2019s hit the <code>oauth<\/code> endpoint so that our server can authenticate with Stormpath. You may ask, \u201cWhat <code>oauth<\/code> endpoint?\u201d The controller above doesn\u2019t indicate any such endpoint. Are there other controllers with other endpoints in the example? No, there are not! Stormpath gives you oauth (and many other) endpoints right out-of-the-box. Check it out:<\/p>\n<pre class=\"brush:java; wrap-lines:false\">\u27a5 http -v --form POST http:\/\/localhost:8080\/oauth\/token  \\\r\n&amp;gt; 'Origin:http:\/\/localhost:8080' \\\r\n&amp;gt; grant_type=password username=micah+demo.jsmith@stormpath.com password=\r\nPOST \/oauth\/token HTTP\/1.1\r\nContent-Type: application\/x-www-form-urlencoded; charset=utf-8\r\nHost: localhost:8080\r\nOrigin: http:\/\/localhost:8080\r\nUser-Agent: HTTPie\/0.9.2\r\n \r\ngrant_type=password&amp;amp;username=micah%2Bdemo.jsmith%40stormpath.com&amp;amp;password=\r\n \r\nHTTP\/1.1 200 OK\r\nCache-Control: no-store\r\nContent-Length: 325\r\nContent-Type: application\/json;charset=UTF-8\r\nDate: Tue, 04 Aug 2015 16:02:08 GMT\r\nPragma: no-cache\r\nServer: Apache-Coyote\/1.1\r\nSet-Cookie: account=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4; Expires=Wed, 05-Aug-2015 16:02:08 GMT; Path=\/; HttpOnly\r\n \r\n{\r\n    \"access_token\": \"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4\",\r\n    \"expires_in\": 259200,\r\n    \"token_type\": \"Bearer\"\r\n}<\/pre>\n<p>There\u2019s a lot going on here, so let\u2019s break it down.<\/p>\n<p>On the first line, I am telling <code>httpie<\/code> that I want to make a form url-encoded POST \u2013 that\u2019s what the <code>--form<\/code> and <code>POST<\/code> parameters do. I am hitting the <code>\/oauth\/token<\/code> endpoint of my locally running server. I specify an <code>Origin<\/code> header. This is required to interact with Stormpath for the security reasons we talked about <a href=\"https:\/\/stormpath.com\/blog\/secure-single-page-app-problem?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">previously<\/a>. As per the OAuth2 spec, I am passing up <code>grant_type=password<\/code> along with a<code>username<\/code> and <code>password<\/code>.<\/p>\n<p>The response has a <code>Set-Cookie<\/code> header as well as a JSON body containing the OAuth2 access token. And guess what? That access token is also a JWT. Here are the claims decoded:<\/p>\n<pre class=\"brush:bash\">{\r\n  \"jti\": \"14426d13-f58b-4a41-bede-0b343fcd1ac0\",\r\n  \"iat\": 1438704128,\r\n  \"sub\": \"https:\/\/api.stormpath.com\/v1\/accounts\/5oM4WI3P4xIwp4WiDbRj80\",\r\n  \"exp\": 1438963328\r\n}<\/pre>\n<p>Notice the <code>sub<\/code> key. That\u2019s the full Stormpath URL to the account I authenticated as. Now, let\u2019s hit our basic Hello World endpoint again, only this time, we will use the OAuth2 access token:<\/p>\n<pre class=\"brush:bash; wrap-lines:false\">\u27a5 http -v localhost:8080 \\\r\n&amp;gt; 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4'\r\nGET \/ HTTP\/1.1\r\nAuthorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4\r\nConnection: keep-alive\r\nHost: localhost:8080\r\nUser-Agent: HTTPie\/0.9.2\r\n \r\n \r\n \r\nHTTP\/1.1 200 OK\r\nContent-Length: 11\r\nContent-Type: text\/plain;charset=UTF-8\r\nDate: Tue, 04 Aug 2015 16:44:28 GMT\r\nServer: Apache-Coyote\/1.1\r\n \r\nHello John!<\/pre>\n<p>Notice on the last line of the output that the message addresses us by name. Now that we\u2019ve established an authenticated session with Stormpath using OAuth2, these lines in the controller retrieve the first name:<\/p>\n<pre class=\"brush:bash\">Account account = AccountResolver.INSTANCE.getAccount(request);\r\nif (account != null) {\r\n    name = account.getGivenName();\r\n}<\/pre>\n<h2>Summary: Token Authentication for Java Apps<\/h2>\n<p>In this post, we\u2019ve looked at how token authentication with JWTs not only addresses the concerns of traditional approaches, but also gives us the benefit of inspectable meta-data and strong cryptographic signatures.<\/p>\n<p>We gave an overview of the OAuth2 protocol and went through a detailed example of how Stormpath\u2019s implementation of OAuth2 uses JWTs.<\/p>\n<p>Here are some other links to posts on token based authentication, JWTs and Spring Boot:<\/p>\n<ul>\n<li><a href=\"https:\/\/stormpath.com\/blog\/token-auth-spa?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">Token Based Authentication for Angular.js<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/jwtk\/jjwt\">JJWT \u2013 JSON Web Token for Java and Android<\/a><\/li>\n<li><a href=\"http:\/\/docs.stormpath.com\/java\/spring-boot-web\/quickstart.html?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=token-auth-for-java&amp;utm_campaign=java-2016\">Spring Boot Webapp Sample Quickstart<\/a><\/li>\n<li><a href=\"https:\/\/tools.ietf.org\/html\/draft-ietf-oauth-json-web-token-32\">JWT Specification<\/a><\/li>\n<\/ul>\n<p><span style=\"font-size: 20px;\">Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and <a href=\"https:\/\/docs.stormpath.com\/java\/?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_term=cta&#038;utm_content=token-auth-for-java&#038;utm_campaign=java-2016\">robust Java SDK support<\/a> can eliminate your security risk and can be implemented in minutes. <a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_term=cta&#038;utm_content=token-auth-for-java&#038;utm_campaign=java-2016\">Sign up<\/a>, and never build auth again!<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your security risk and can be implemented in minutes. Sign up, and never build auth again! Update 5\/12\/2016: Building a Java application? JJWT is a Java library providing end-to-end JWT creation and verification, developed by our &hellip;<\/p>\n","protected":false},"author":1062,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[1373,297,1366],"class_list":["post-58652","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-authentication","tag-security","tag-stormpath"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Token Authentication for Java Applications - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Token Authentication for Java Applications - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-07-25T09:10:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-08-01T20:48:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Micah Silverman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Micah Silverman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html\"},\"author\":{\"name\":\"Micah Silverman\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fd211fe0d3a9791d30dd0ca5276d9660\"},\"headline\":\"Token Authentication for Java Applications\",\"datePublished\":\"2016-07-25T09:10:57+00:00\",\"dateModified\":\"2016-08-01T20:48:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html\"},\"wordCount\":2256,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"Authentication\",\"Security\",\"stormpath\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html\",\"name\":\"Token Authentication for Java Applications - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2016-07-25T09:10:57+00:00\",\"dateModified\":\"2016-08-01T20:48:02+00:00\",\"description\":\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/07\\\/token-authentication-java-applications.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Token Authentication for Java Applications\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fd211fe0d3a9791d30dd0ca5276d9660\",\"name\":\"Micah Silverman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"caption\":\"Micah Silverman\"},\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/micah-silverman\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Token Authentication for Java Applications - Java Code Geeks","description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html","og_locale":"en_US","og_type":"article","og_title":"Token Authentication for Java Applications - Java Code Geeks","og_description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","og_url":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2016-07-25T09:10:57+00:00","article_modified_time":"2016-08-01T20:48:02+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Micah Silverman","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Micah Silverman","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html"},"author":{"name":"Micah Silverman","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fd211fe0d3a9791d30dd0ca5276d9660"},"headline":"Token Authentication for Java Applications","datePublished":"2016-07-25T09:10:57+00:00","dateModified":"2016-08-01T20:48:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html"},"wordCount":2256,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["Authentication","Security","stormpath"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html","url":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html","name":"Token Authentication for Java Applications - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2016-07-25T09:10:57+00:00","dateModified":"2016-08-01T20:48:02+00:00","description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2016\/07\/token-authentication-java-applications.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Token Authentication for Java Applications"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fd211fe0d3a9791d30dd0ca5276d9660","name":"Micah Silverman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","caption":"Micah Silverman"},"url":"https:\/\/www.javacodegeeks.com\/author\/micah-silverman"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/58652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/1062"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=58652"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/58652\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=58652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=58652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=58652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}