{"id":20900423,"url":"https://github.com/rahul-ghadge/spring-boot-hmac-auth","last_synced_at":"2026-04-29T19:34:15.003Z","repository":{"id":174154583,"uuid":"613871776","full_name":"rahul-ghadge/spring-boot-hmac-auth","owner":"rahul-ghadge","description":"Spring boot Hmac Authentication for CRUD APIs","archived":false,"fork":false,"pushed_at":"2023-06-10T09:54:43.000Z","size":3023,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T19:44:47.880Z","etag":null,"topics":["hmac","hmac-authentication","hmac-sha256","rest-api","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rahul-ghadge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-14T12:47:33.000Z","updated_at":"2023-04-04T09:56:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"9f93a388-650b-437e-9c12-3b5c4db26e63","html_url":"https://github.com/rahul-ghadge/spring-boot-hmac-auth","commit_stats":null,"previous_names":["rahul-ghadge/spring-boot-hmac-auth"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rahul-ghadge/spring-boot-hmac-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rahul-ghadge%2Fspring-boot-hmac-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rahul-ghadge%2Fspring-boot-hmac-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rahul-ghadge%2Fspring-boot-hmac-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rahul-ghadge%2Fspring-boot-hmac-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rahul-ghadge","download_url":"https://codeload.github.com/rahul-ghadge/spring-boot-hmac-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rahul-ghadge%2Fspring-boot-hmac-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32441274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T18:12:22.909Z","status":"ssl_error","status_checked_at":"2026-04-29T18:11:33.322Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hmac","hmac-authentication","hmac-sha256","rest-api","spring-boot"],"created_at":"2024-11-18T11:19:29.468Z","updated_at":"2026-04-29T19:34:14.983Z","avatar_url":"https://github.com/rahul-ghadge.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Spring boot Hmac Authentication\n\nHmac (Hash-based Message Authentication Code) authentication is the technique used to simultaneously verify both the data integrity and authenticity of a message.\nIt consists of the **Secret Key** and the **Hash Function** which guarantees the integrity of the message between two parties.\n\nHMAC uses cryptographic hash functions such as **MD5** and **SHA-***_(MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512_)\n\nJava provides built-in support for Mac class. We need to add only dependencies for parsing data and ease of code.\n\n\n## Prerequisites\n- Java\n- [Spring Boot](https://spring.io/projects/spring-boot)\n- [Maven](https://maven.apache.org/guides/index.html)\n- Basic Cryptographic knowledge\n- [Lombok](https://objectcomputing.com/resources/publications/sett/january-2010-reducing-boilerplate-code-with-project-lombok)\n\n\n## Tools\n- Eclipse or IntelliJ IDEA (or any preferred IDE) with embedded Maven\n- Maven (version \u003e= 3.6.0)\n- Postman (or any RESTful API testing tool)\n\n\n\u003cbr/\u003e\n\n\n###  Build and Run application\n_GOTO \u003e_ **~/absolute-path-to-directory/spring-boot-hmac-auth**  \nand try below command in terminal\n\u003e **```mvn spring-boot:run```** it will run application as spring boot application\n\nor\n\u003e **```mvn clean install```** it will build application and create **jar** file under target directory\n\nRun jar file from below path with given command\n\u003e **```java -jar ~/path-to-spring-boot-hmac-auth/target/spring-boot-hmac-auth-0.0.1-SNAPSHOT.jar```**\n\nOr\n\u003e run **main method** from `SpringBootHmacAuthApplication.java` as spring boot application.\n\n\n\n\n\n### Code Snippets\n1. #### Maven Dependencies\n   Need to add below dependencies to enable web support related config in **pom.xml**. Lombok's dependency is to get rid of boiler-plate code.\n    ```\n    \u003cdependency\u003e\n       \u003cgoupId\u003eorg.springframework.boot\u003c/groupId\u003e\n       \u003cartifactId\u003espring-boot-starter-web\u003c/artifactId\u003e\n    \u003c/dependency\u003e\n\n    \u003cdependency\u003e\n       \u003cgroupId\u003eorg.projectlombok\u003c/groupId\u003e\n       \u003cartifactId\u003elombok\u003c/artifactId\u003e\n       \u003coptional\u003etrue\u003c/optional\u003e\n    \u003c/dependency\u003e\n\n    \u003cdependency\u003e\n       \u003cgroupId\u003ejavax.servlet\u003c/groupId\u003e\n       \u003cartifactId\u003ejavax.servlet-api\u003c/artifactId\u003e\n       \u003cversion\u003e4.0.1\u003c/version\u003e\n    \u003c/dependency\u003e\n    ```\n\n\n\n2. #### Properties file\n   Reading H2 DB related properties from **application.properties** file and configuring JPA connection factory for H2 database.\n\n   **src/main/resources/application.properties**\n   ```\n   hmac-auth:\n     header:\n       nonce: nonce\n       access-key: accesskey\n       authorization: authorization\n   \n     access-key: 8c2ea66e-abfc-4394-8adb-fa52890bdce3\n     secret-key: 982064c6-c265-11ed-afa1-0242ac120002\n     expires: 60    # seconds\n   ```\n\n\n3. #### Model class\n   Below model class which we will use to perform CRUD operations if authentication is successful.  \n   **SuperHero.java**\n    ```\n    @Data\n    @AllArgsConstructor\n    @NoArgsConstructor\n    @Builder\n    public class SuperHero implements Serializable {\n    \n        @Id\n        @GeneratedValue\n        private int id;\n    \n        private String name;\n        private String superName;\n        private String profession;\n        private int age;\n        private boolean canFly;\n    \n        // Constructor, Getter and Setter\n    }\n    ```\n\n\n4. #### Hmac Authentication\n   All classes from config package are used to authenticate users with Hmac.\n   - _config_\n     - _filter_\n       - **HmacInterceptor** - Which will intercept each request and validate the auth token is valid and not expired\n     - _properties_\n       - **HmacProperties** - Read properties from application.properties and configure Hmac objects.\n     - _verifier_\n       - **CredentialsVerifier** - Will verify the access kay and nonce (token is expired or not).\n       - **HmacAuthVerifier** - This class is the core of Hmac authentication. It will validate all the things regarding request metadata \n                and body under **verify method**. Will verify the cryptographic _algorithm, headers and token_ as well for coming requests.\n     - _web_\n       - **HmacVerifyConfig** - Here we'll register HmacInterceptor interceptor in the spring interceptor registry.\n   - **CredentialsProvider** - Plain interface with some abstract methods for credentials provider.\n   - **HmacAuthBeanConfig** - Hmac auth related beans like **HmacInterceptor** and **CredentialsProvider** for spring application by reading **HmacProperties**.\n   - **HmacHelper** - Helper class to read Http request and extract data from it generate signature request of Hmac authentication.\n   - **HmacSignature** - Class which contains signature methods to return Hmac token by using cryptographic algorithm, http request and secret.\n\n\n\n\n\n5. #### Get token operation for Super Heroes\n\n   In **HmacKeyController.java** class,\n   we have exposed 5 endpoints for basic CRUD operations which are under SuperHeroController. This controller will generate token for each request which we'll be validating under\n     superHeroController.\n    - GET token for All Super Heroes\n    - GET token for ID\n    - POST token to store Super Hero in DB\n    - PUT token for to update Super Hero\n    - DELETE token for ID\n\n    ```\n    @RestController\n    @RequestMapping(\"/hmac-key/super-heroes\")\n    public class HmacKeyController {\n\n        @GetMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e findById(HttpServletRequest httpServletRequest) throws IOException;\n\n        @GetMapping\n        public ResponseEntity\u003cList\u003c?\u003e\u003e findAll(HttpServletRequest httpServletRequest) throws IOException;\n\n        @PostMapping\n        public ResponseEntity\u003c?\u003e save(HttpServletRequest httpServletRequest) throws IOException;\n\n        @PutMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e update(HttpServletRequest httpServletRequest) throws IOException;\n    \n        @DeleteMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e delete(HttpServletRequest httpServletRequest) throws IOException;\n    }\n    ```\n\n\n6. #### CRUD operation for Super Heroes\n\n   In **SuperHeroController.java** class,\n   we have exposed 5 endpoints for basic CRUD operations\n    - GET All Super Heroes\n    - GET by ID\n    - POST to store Super Hero in DB\n    - PUT to update Super Hero\n    - DELETE by ID\n\n   But here we'll validate request before executing the actual logic and check the token is valid or not under HmacInterceptor class. \n    This will intercept each request and allow for only valid tokens.\n\n    ```\n    @RestController\n    @RequestMapping(\"/super-hero\")\n    public class SuperHeroController {\n\n        @GetMapping\n        public ResponseEntity\u003cList\u003c?\u003e\u003e findAll();\n\n        @GetMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e findById(@PathVariable String id);\n\n        @PostMapping\n        public ResponseEntity\u003c?\u003e save(@RequestBody SuperHero superHero);\n\n        @PutMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e update(@PathVariable int id, @RequestBody SuperHero superHero);\n    \n        @DeleteMapping(\"/{id}\")\n        public ResponseEntity\u003c?\u003e delete(@PathVariable String id);\n    }\n    ```\n\n\n7. ### API Endpoints\n\n    \u003e **GET** http://localhost:8080/hmac-key/super-heroes # /hmac-key is important here\n\n    #### Response\n    ```\n    {\n        authorization: \"HmacSHA256:3+na/n6Htt2MnRQzEtYYISy5l7O/GzHDtVyisDhNT/Q=\",\n        nonce: \"1678793259142\"\n    }\n    ```\n\n    #### Try above authorization code and nonce in below request as header\n\n    \u003e **GET** http://localhost:8080/v1/super-heroes\n\n    ### Request headers\n    ```\n    accessKey: 8c2ea66e-abfc-4394-8adb-fa52890bdce3\n    authorization: HmacSHA256:3+na/n6Htt2MnRQzEtYYISy5l7O/GzHDtVyisDhNT/Q=\n    nonce: 1678793259142\n    ```\n\n    ---\n   \n    \u003e **GET** http://localhost:8080/hmac-key/super-heroes/1\n   \n    ### Response\n    ```\n    {\n        authorization: \"HmacSHA256:mHQeVAoGpDv7aSGLtDQ664gr7t47JL71NHNktj4w6hQ='\n        nonce: \"1678791858860\"\n    }\n    ```\n   #### Try above authorization code and nonce in below request as header\n\n    \u003e **GET** http://localhost:8080/v1/super-heroes/1\n\n    ### Request headers   \n    ```\n    accessKey: 8c2ea66e-abfc-4394-8adb-fa52890bdce3\n    authorization: HmacSHA256:mHQeVAoGpDv7aSGLtDQ664gr7t47JL71NHNktj4w6hQ=\n    nonce: 1678791858860\n    ```\n\n    ---\n\n    \u003e **POST** http://localhost:8080/hmac-key/super-heroes\n\n    ### Request\n\n    ```\n    curl --location --request POST 'http://localhost:8080/hmac-key/super-heroes' \\\n    --header 'Content-Type: application/json' \\\n    --data-raw ' {\n            \"id\": 10,\n           \"name\": \"Tony\",\n           \"superName\": \"Iron Man\",\n           \"profession\": \"Business\",\n           \"age\": 50,\n           \"canFly\": true\n       }'\n    ```\n\n    ### Response\n    ```\n    {\n        \"authorization\": \"HmacSHA256:GGNhJT44kpnAozc/wf+a5I6IS+TyVV/nBTvrFh6Miwc=\",\n        \"nonce\": \"1678796605841\"\n    }\n    ```\n\n    #### Try above authorization code and nonce in below request as header\n\n    \u003e **POST** http://localhost:8080/v1/super-heroes\n\n    ### Request\n    ```\n    curl --location --request POST 'http://localhost:8080/v1/super-heroes' \\\n    --header 'accessKey: 8c2ea66e-abfc-4394-8adb-fa52890bdce3' \\\n    --header 'authorization: HmacSHA256:GGNhJT44kpnAozc/wf+a5I6IS+TyVV/nBTvrFh6Miwc=' \\\n    --header 'nonce: 1678796605841' \\\n    --header 'Content-Type: application/json' \\\n    --data-raw '{\n            \"id\": 10,\n           \"name\": \"Tony\",\n           \"superName\": \"Iron Man\",\n           \"profession\": \"Business\",\n           \"age\": 50,\n           \"canFly\": true\n       }'\n    ```\n\n---\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frahul-ghadge%2Fspring-boot-hmac-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frahul-ghadge%2Fspring-boot-hmac-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frahul-ghadge%2Fspring-boot-hmac-auth/lists"}