How To Achieve User Authentication By Web3 Wallet Using Spring Security, JWTs, Web3j & Kotlin
One of the greatest things that a web3 enabled browser gives us is saying goodbye to our primal ways of authenticating users with a username & password combination.
If you're looking to authenticate users using a metamask or any web3 wallet then continue reading this article or simply explore the minimal code here: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo
You can checkout the code and follow along, or start fresh from spring initializer and start fresh, or add whatever you learned here to your existing project!
How Does This Work?
- The minimal frontend code uses web3js to request the user to sign a message using their web3 enabled browser.
- The backend receives the message and makes sure that the person who signed it is the one who called the controller login action by comparing the public key of the user with public key that is extracted from the signed message.
- If the login is successful, a jwt is generated by spring security and we send it back to the frontend.
- Frontend uses the jwt to call authenticated actions.
Necessities
Be sure to take a look at the pom: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/pom.xml and grab whatever your project is missing.
Add and configure your application.properties similarly to this: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/src/main/resources/application.properties
Spring Security Configuration
Killing CORS: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/src/main/kotlin/com/example/demo/config/WebMvcConfig.kt
Adding authenticated paths, adding our simple "NoPasswordEncoder" inline class, and other spring security configurations: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/src/main/kotlin/com/example/demo/config/SecurityConfig.kt
Controller Actions
Two actions needed to demonstrate this: 1. Authentication action to generate the jwt and make sure you are the signer of the message. 2. A detail fetching service that requires a live jwt token to demonstrate that we're actually logged in. And we actually fetch who the calling user is using the token which is another nice convenience when building dApps.
Both of these can be found here: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/src/main/kotlin/com/example/demo/controller/UserController.kt
Spring Security Things
This part of the demo can honestly be copied and pasted but I recommend reading over it to know what's going on. It's basically giving us the @CurrentUser annotation, telling spring security that we're using jwts, and everything in between. It's all here: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/tree/master/src/main/kotlin/com/example/demo/security
Demonstrative Frontend
Our frontend is very minimal and only used to call two things: 1. POST /api/user -> To create the user entity in the database for the current public address of the user calling it. And generating a jwt for the user to use for further interactions with the dApp. The jwt gets saved in localStorage. 2. GET /api/userDetails -> To get the details if jwt is valid. To show the unathenticated resposne if the jwt isn't, or if there isn't one in the browser's localStorage.
The frontend's bread and butter is here: https://github.com/hshar7/springsecurity-web3-jwt-auth-demo/blob/master/demo_frontend/src/views/LandingPage/LandingPage.jsx
How To Run
- Frontend:
npm install & npm start
- Backend: I'd just launch the project with intellij but you can also do
mvn clean install
then run the generated jar file that is in the target folder usingjava -jar ***
Special Thanks
To Callicoder for this tutorial series that taught me how to do spring security authentication using passwords. https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-1/
- Kauri original title: How To Achieve User Authentication By Web3 Wallet Using Spring Security, JWTs, Web3j & Kotlin
- Kauri original link: https://kauri.io/how-to-achieve-user-authentication-by-web3-wallet/a7a3198e2673406aa730d41854871e1a/a
- Kauri original author: Hayder Sharhan (@hshar)
- Kauri original Publication date: 2019-08-19
- Kauri original tags: jwt, web3j, kotlin, springboot
- Kauri original hash: QmbBAwBTVkP2ggLEMHZwd8Lm5VcYRgiWXacQiKEJup68Eg
- Kauri original checkpoint: Qmekp5iiDi5N5M4KdtAVGBEJEF3ahMgWYZJqL7s1qmkQ9g