{"id":75734,"date":"2018-04-10T16:00:44","date_gmt":"2018-04-10T13:00:44","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=75734"},"modified":"2018-04-10T12:30:34","modified_gmt":"2018-04-10T09:30:34","slug":"user-authentication-best-practices-checklist","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html","title":{"rendered":"User Authentication Best Practices Checklist"},"content":{"rendered":"<p>User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many times. And yet there are so many mistakes made all the time.<\/p>\n<p>Part of the reason for that is that the list of things that can go wrong is long. You can store passwords incorrectly, you can have a vulnerably password reset functionality, you can expose your session to a CSRF attack, your session can be hijacked, etc. So I\u2019ll try to compile a list of best practices regarding user authentication. <a href=\"https:\/\/www.owasp.org\/images\/7\/72\/OWASP_Top_10-2017_%28en%29.pdf.pdf\">OWASP top 10<\/a> is always something you should read, every year. But that might not be enough.<\/p>\n<p>So, let\u2019s start. I\u2019ll try to be concise, but I\u2019ll include as much of the related pitfalls as I can cover \u2013 e.g. what could go wrong with the user session after they login:<\/p>\n<ul>\n<li>Store passwords with <a href=\"https:\/\/www.javacodegeeks.com\/2012\/08\/bcrypt-salt-its-bare-minimum.html\">bcrypt\/scrypt\/PBKDF2<\/a>. No MD5 or SHA, as they are not good for password storing. Long salt (per user) is mandatory (the aforementioned algorithms have it built in). If you don\u2019t and someone gets hold of your database, they\u2019ll be able to extract the passwords of all your users. And then try these passwords on other websites.<\/li>\n<li>Use HTTPS. Period. (Otherwise user credentials can leak through unprotected networks). Force HTTPS if user opens a plain-text version. And make sure you use only the latest protocol (TLS 1.2 at the moment; TLS 1.1 doesn\u2019t seem to have vulnerabilities, so it can also be supported). You can do a <a href=\"https:\/\/www.qualys.com\/forms\/freescan\/\">Qualys Scan<\/a> to check whether your supported protocol versions are OK.<\/li>\n<li>Mark cookies as <a href=\"https:\/\/en.wikipedia.org\/wiki\/HTTP_cookie#Secure_cookie\"><code>secure<\/code><\/a>. Makes cookie theft harder.<\/li>\n<li>Use CSRF protection (e.g. CSRF one-time tokens that are verified with each request). Frameworks have such functionality built-in.<\/li>\n<li>Disallow framing (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/X-Frame-Options\"><code>X-Frame-Options: DENY<\/code><\/a>). Otherwise your website may be included in another website in a hidden iframe and \u201cabused\u201d through javascript.<\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Security\/Same-origin_policy\">Have a same-origin policy<\/a><\/li>\n<li>Logout \u2013 let your users logout by deleting all cookies and invalidating the session. This makes usage of shared computers safer (yes, users should ideally use private browsing sessions, but not all of them are that savvy)<\/li>\n<li>Session expiry \u2013 don\u2019t have forever-lasting sessions. If the user closes your website, their session should expire after a while. \u201cA while\u201d may still be a big number depending on the service provided. For ajax-heavy website you can have regular ajax-polling that keeps the session alive while the page stays open.<\/li>\n<li>Remember me \u2013 implementing \u201cremember me\u201d (on this machine) functionality is actually hard due to the risks of a stolen persistent cookie. <a href=\"http:\/\/jaspan.com\/improved_persistent_login_cookie_best_practice\">Spring-security uses this approach<\/a>, which I think should be followed if you wish to implement more persistent logins.<\/li>\n<li>Forgotten password flow \u2013 the forgotten password flow should rely on sending a one-time (or expiring) link to the user and asking for a new password when it\u2019s opened. <a href=\"https:\/\/auth0.com\/learn\/password-reset\/\">0Auth explain it in this post<\/a> and Postmark <a href=\"https:\/\/postmarkapp.com\/guides\/password-reset-email-best-practices\">gives some best pracitces<\/a>. How the link is formed is a separate discussion and there are several approaches. Store a <a href=\"https:\/\/stackoverflow.com\/questions\/19262252\/time-limited-or-one-time-use-password-reset-tokens\">password-reset token<\/a> in the user profile table and then send it as parameter in the link. Or do not store anything in the database, but send a few params: <code>userId:expiresTimestamp:hmac(userId+expiresTimestamp)<\/code>. That way you have expiring links (rather than one-time links). The HMAC relies on a secret key, so the links can\u2019t be spoofed. It seems, however, that there\u2019s no consensus on this topic, as the <a href=\"https:\/\/www.owasp.org\/index.php\/Forgot_Password_Cheat_Sheet\">OWASP guide has a bit different approach<\/a><\/li>\n<li>One-time login links \u2013 this is an option used by Slack, which sends one-time login links instead of asking users for passwords. It relies on the fact that your email is well guarded and you have access to it all the time. If your service is not accessed to often, you can have that approach instead of (rather than in addition to) passwords.<\/li>\n<li>Limit login attempts \u2013 brute-force through a web UI should not be possible; therefore you should block login attempts if they become too many. One approach is to just block them based on IP. The other one is to block them based on account attempted. (<a href=\"http:\/\/www.baeldung.com\/spring-security-block-brute-force-authentication-attempts\">Spring example here<\/a>). Which one is better \u2013 I don\u2019t know. Both can actually be combined. Instead of fully blocking the attempts, you may add a captcha after, say, the 5th attempt. But don\u2019t add the captcha for the first attempt \u2013 it is bad user experience.<\/li>\n<li>Don\u2019t leak information through error messages \u2013 you shouldn\u2019t allow attackers to figure out if an email is registered or not. If an email is not found, upon login report just \u201cIncorrect credentials\u201d. On passwords reset, it may be something like \u201cIf your email is registered, you should have received a password reset email\u201d. This is often at odds with usability \u2013 people don\u2019t often remember the email they used to register, and the ability to check a number of them before getting in might be important. So this rule is not absolute, though it\u2019s desirable, especially for more critical systems.<\/li>\n<li>Make sure you use <a href=\"https:\/\/www.javacodegeeks.com\/2018\/03\/using-jwt-sessions.html\">JWT only if it\u2019s really necessary<\/a> and be careful of the pitfalls.<\/li>\n<li>Consider using a 3rd party authentication \u2013 OpenID Connect, OAuth by Google\/Facebook\/Twitter (but be careful with <a href=\"http:\/\/homakov.blogspot.bg\/2013\/02\/hacking-facebook-with-oauth2-and-chrome.html\">OAuth flaws as well<\/a>). There\u2019s an associated risk with relying on a 3rd party identity provider, and you still have to manage cookies, logout, etc., but some of the authentication aspects are simplified.<\/li>\n<li>For high-risk or sensitive applications <a href=\"https:\/\/www.javacodegeeks.com\/2017\/10\/enabling-two-factor-authentication-web-application.html\">use 2-factor authentication<\/a>. There\u2019s a caveat with Google Authenticator though \u2013 if you lose your phone, you lose your accounts (unless there\u2019s a manual process to restore it). That\u2019s why Authy seems like a good solution for storing 2FA keys.<\/li>\n<\/ul>\n<p>I\u2019m sure I\u2019m missing something. And you see it\u2019s complicated. Sadly we\u2019re still at the point where the most common functionality \u2013 authenticating users \u2013 is so tricky and cumbersome, that you almost always get at least some of it wrong.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Java Code Geeks with permission by Bozhidar Bozhanov, partner at our <a href=\"\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener\">JCG program<\/a>. See the original article here: <a href=\"https:\/\/techblog.bozho.net\/user-authentication-best-practices-checklist\/\" target=\"_blank\" rel=\"noopener\">User Authentication Best Practices Checklist<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many times. And yet there are so many mistakes made all the time. Part of the reason for that is that the list of things that can go wrong is long. You &hellip;<\/p>\n","protected":false},"author":55,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-75734","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>User Authentication Best Practices Checklist - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many\" \/>\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\/2018\/04\/user-authentication-best-practices-checklist.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"User Authentication Best Practices Checklist - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.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=\"2018-04-10T13:00:44+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=\"Bozhidar Bozhanov\" \/>\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=\"Bozhidar Bozhanov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html\"},\"author\":{\"name\":\"Bozhidar Bozhanov\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/1eaacbb8d159c99fd32e6b51198a1e79\"},\"headline\":\"User Authentication Best Practices Checklist\",\"datePublished\":\"2018-04-10T13:00:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html\"},\"wordCount\":1030,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html\",\"name\":\"User Authentication Best Practices Checklist - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2018-04-10T13:00:44+00:00\",\"description\":\"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.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\\\/2018\\\/04\\\/user-authentication-best-practices-checklist.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\":\"User Authentication Best Practices Checklist\"}]},{\"@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\\\/1eaacbb8d159c99fd32e6b51198a1e79\",\"name\":\"Bozhidar Bozhanov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/12\\\/bozhidar.bozhanov.jpg\",\"caption\":\"Bozhidar Bozhanov\"},\"description\":\"Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE, as well as Android, Scala and any framework you throw at him. creator of Computoser - an algorithmic music composer. Worked on telecom projects, e-government and large-scale online recruitment and navigation platforms.\",\"sameAs\":[\"http:\\\/\\\/techblog.bozho.net\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/bozhidar-bozhanov\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"User Authentication Best Practices Checklist - Java Code Geeks","description":"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many","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\/2018\/04\/user-authentication-best-practices-checklist.html","og_locale":"en_US","og_type":"article","og_title":"User Authentication Best Practices Checklist - Java Code Geeks","og_description":"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many","og_url":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2018-04-10T13:00:44+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":"Bozhidar Bozhanov","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bozhidar Bozhanov","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html"},"author":{"name":"Bozhidar Bozhanov","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/1eaacbb8d159c99fd32e6b51198a1e79"},"headline":"User Authentication Best Practices Checklist","datePublished":"2018-04-10T13:00:44+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html"},"wordCount":1030,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html","url":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html","name":"User Authentication Best Practices Checklist - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2018-04-10T13:00:44+00:00","description":"User authentication is the functionality that every web application shared. We should have perfected that a long time ago, having implemented it so many","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/04\/user-authentication-best-practices-checklist.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\/2018\/04\/user-authentication-best-practices-checklist.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":"User Authentication Best Practices Checklist"}]},{"@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\/1eaacbb8d159c99fd32e6b51198a1e79","name":"Bozhidar Bozhanov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/12\/bozhidar.bozhanov.jpg","caption":"Bozhidar Bozhanov"},"description":"Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE, as well as Android, Scala and any framework you throw at him. creator of Computoser - an algorithmic music composer. Worked on telecom projects, e-government and large-scale online recruitment and navigation platforms.","sameAs":["http:\/\/techblog.bozho.net\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/bozhidar-bozhanov"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/75734","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\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=75734"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/75734\/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=75734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=75734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=75734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}