{"id":23122310,"url":"https://github.com/andrecaiado/spring-boot-security-auth","last_synced_at":"2026-05-05T13:37:08.495Z","repository":{"id":245163092,"uuid":"817421234","full_name":"andrecaiado/spring-boot-security-auth","owner":"andrecaiado","description":"Spring Boot application that implements spring security for authentication and authorization","archived":false,"fork":false,"pushed_at":"2024-08-14T14:14:29.000Z","size":1072,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-26T16:09:22.501Z","etag":null,"topics":["docker","docker-compose","java","jwt","spring-boot","spring-security","testing"],"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/andrecaiado.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":"2024-06-19T17:07:20.000Z","updated_at":"2024-08-19T14:32:17.000Z","dependencies_parsed_at":"2024-12-17T07:19:17.973Z","dependency_job_id":"d934948b-1760-40dd-abc9-33d6ef5007ca","html_url":"https://github.com/andrecaiado/spring-boot-security-auth","commit_stats":null,"previous_names":["andrecaiado/spring-boot-security-auth"],"tags_count":0,"template":false,"template_full_name":"andrecaiado/spring-boot-template","purl":"pkg:github/andrecaiado/spring-boot-security-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrecaiado%2Fspring-boot-security-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrecaiado%2Fspring-boot-security-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrecaiado%2Fspring-boot-security-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrecaiado%2Fspring-boot-security-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrecaiado","download_url":"https://codeload.github.com/andrecaiado/spring-boot-security-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrecaiado%2Fspring-boot-security-auth/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262099728,"owners_count":23258670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["docker","docker-compose","java","jwt","spring-boot","spring-security","testing"],"created_at":"2024-12-17T07:18:41.595Z","updated_at":"2026-05-05T13:37:03.447Z","avatar_url":"https://github.com/andrecaiado.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Boot Security Authentication and Authorization project\n\nThis is a Spring Boot application that implements Spring Security for authentication and authorization.\n\n## Contents\n\n- [Features](#features)\n- [Dependencies](#dependencies)\n- [Implementation](#implementation)\n  - [Spring Security Authentication Flow for DaoAuthenticationProvider](#spring-security-authentication-flow-for-daoauthenticationprovider)\n  - [Spring Security Implementation](#spring-security-implementation)\n    - [Security Filter Chain](#security-filter-chain)\n    - [Authentication Manager](#authentication-manager)\n    - [UserDetailsService](#userdetailservice)\n    - [JwtAuthorizationFilter](#jwtauthorizationfilter)\n  - [Security Exception Handling](#security-exception-handling)\n    - [JwtAuthenticationEntryPoint](#jwtauthenticationentrypoint)\n    - [AccessDeniedHandlerJwt](#accessdeniedhandlerjwt)\n\n# Features\n\n- Exposes endpoints to register and authenticate users (with username and password)\n- Exposes endpoints to get user details\n- Uses Spring Security for authentication and authorization\n- Generates a JWT token for authenticated users to be used in subsequent requests\n- Generates a refresh token to refresh the JWT token\n- Stores the user details in a PostgreSQL database\n\n**Additional features**:\n\n- Uses Spring Data JPA for database operations\n- Uses Flyway for database migrations\n- Uses Spring Boot Docker Compose to start and stop a Docker container running the PostgreSQL database\n- Includes a datasource configuration for testing purposes that uses the H2 in-memory database\n\nIn this readme file, we will focus on the implementation of the security features. For more details about the additional features, please refer to the [Spring Boot Template project](https://github.com/andrecaiado/spring-boot-template).\n\n# Dependencies\n\nTo use Spring Security, we added the Spring Boot Starter Security dependency to the `pom.xml` file.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-security\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\nTo use JWT tokens, we added the following dependencies to the `pom.xml` file.\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.jsonwebtoken\u003c/groupId\u003e\n  \u003cartifactId\u003ejjwt-api\u003c/artifactId\u003e\n  \u003cversion\u003e0.11.5\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.jsonwebtoken\u003c/groupId\u003e\n    \u003cartifactId\u003ejjwt-impl\u003c/artifactId\u003e\n    \u003cversion\u003e0.11.5\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.jsonwebtoken\u003c/groupId\u003e\n    \u003cartifactId\u003ejjwt-jackson\u003c/artifactId\u003e\n    \u003cversion\u003e0.11.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n# Implementation\n\n## Spring Security Authentication Flow for DaoAuthenticationProvider\n\nIn this project, we are using a Username and Password authentication mechanism.\nThe basic use case for this mechanism consists in a POST request being sent to an authentication specific endpoint with the username and password in the request body. The application authenticates the user and returns a JWT token.\n\nBecause we are storing the user details in a database, we use the `DaoAuthenticationProvider` to authenticate the users.\n\nThe implementation of the authentication mechanism is based on the following components and workflow:\n\n![dao-auth-prov.png](src%2Fmain%2Fresources%2Fdao-auth-prov.png)\n\n*[DaoAuthenticationProvider Usage (image from Spring documentation)](https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/dao-authentication-provider.html)*\n\nComponents and workflow description ([from Spring documentation](https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/dao-authentication-provider.html)):\n\n1 - A UsernamePasswordAuthenticationToken is passed to the AuthenticationManager, which is implemented by ProviderManager.\n\n2 - The ProviderManager is configured to use an AuthenticationProvider of type DaoAuthenticationProvider.\n\n3 - DaoAuthenticationProvider looks up the UserDetails from the UserDetailsService.\n\n4 - DaoAuthenticationProvider uses the PasswordEncoder to validate the password on the UserDetails returned in the previous step.\n\n5 - When authentication is successful, the Authentication that is returned is of type UsernamePasswordAuthenticationToken and has a principal that is the UserDetails returned by the configured UserDetailsService. Ultimately, the returned UsernamePasswordAuthenticationToken is set on the SecurityContextHolder by the authentication Filter.\n\n## Spring Security Implementation\n\nIn order to use Spring Security, we need to create a configuration class and annotate it with `@EnableWebSecurity`.\nIn this project, the security configuration is implemented in the [SecurityConfiguration.java](src%2Fmain%2Fjava%2Fcom%2Fexample%2Fspringbootsecurityauth%2Fconfig%2FSecurityConfiguration.java) class.\n\nIn this configuration class, we define the security filter chain, the authentication manager and the password encoder.\n```java\n@Configuration\n@EnableWebSecurity\npublic class SecurityConfiguration {\n    @Bean\n    public SecurityFilterChain securityFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {\n      ...\n    }\n    \n    @Bean\n    public AuthenticationManager authenticationManager() {\n      ...\n    }\n    \n    @Bean\n    public PasswordEncoder passwordEncoder() {\n      return new BCryptPasswordEncoder();\n    }\n  \n}\n```\n\n### Security Filter Chain\n\nThe security filter chain is a list of filters that are executed in a specific order. Each filter is responsible for a specific task, such as authorizing the access to specific endpoints or processing the JWT token from the request header.\n\nIn this project, we are using the following filters:\n\n- `CsrfFilter`: Prevents CSRF attacks (currently disabled but should be enabled on production)\n- `ExceptionHandling`: Handles exceptions thrown during the authentication process\n- `SessionManagement`: Set the session management to be stateless because we don't want to store the session in the server\n- `AuthorizeRequests`: Authorizes the requests based on the request matchers\n- `AuthenticationManager`: Authenticates the user based on the username and password\n- `JwtAuthenticationFilter`: Processes the JWT token from the request header. This filter is added in a `addFilterBefore` filter so a JWT authentication is processed before a username and password authentication.\n\nThe `SecurityFilterChain` is configured in the [SecurityConfiguration.java](src%2Fmain%2Fjava%2Fcom%2Fexample%2Fspringbootsecurityauth%2Fconfig%2FSecurityConfiguration.java) class.\n\n```java\n@Bean\npublic SecurityFilterChain securityFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {\n  return http\n          .csrf(cr-\u003ecr.disable())\n          .exceptionHandling(\n                  ex -\u003e ex.accessDeniedHandler(accessDeniedHandlerJwt)\n                          .authenticationEntryPoint(jwtAuthenticationEntryPoint)\n          )\n          .sessionManagement(session-\u003esession\n                  .sessionCreationPolicy(SessionCreationPolicy.STATELESS))\n          .authorizeHttpRequests(req -\u003e\n                  req.requestMatchers(\"/auth/**\").permitAll()\n                          .requestMatchers(\"/admin/**\").hasAuthority(\"ROLE_ADMIN\")\n                          .anyRequest().authenticated()\n          )\n          .authenticationManager(authenticationManager)\n          .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)\n          .build();\n}\n```\n\n### Authentication Manager\n\nThe authentication manager is responsible for authenticating the user based on the username and password. It delegates the authentication process to one or more authentication providers.\n\nIn this project, we are using the `DaoAuthenticationProvider` as the authentication provider. The `DaoAuthenticationProvider` uses the `UserDetailsService` to load the user details from the database and the `PasswordEncoder` to verify the password.\n\nThe `AuthenticationManager` is configured in the [SecurityConfiguration.java](src%2Fmain%2Fjava%2Fcom%2Fexample%2Fspringbootsecurityauth%2Fconfig%2FSecurityConfiguration.java) class.\n\n```java\n@Bean\npublic AuthenticationManager authenticationManager() {\n    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();\n    authenticationProvider.setUserDetailsService(userDetailsService);\n    authenticationProvider.setPasswordEncoder(passwordEncoder());\n\n    return new ProviderManager(authenticationProvider);\n}\n```\n\n### UserDetailsService\n\nThe `UserDetailsService` interface is used to retrieve user-related data. It has one method, `loadUserByUsername`, which is used to load the user based on the username. The `UserDetailsService` interface is implemented by the [UserDetailsServiceImpl.java](src%2Fmain%2Fjava%2Fcom%2Fexample%2Fspringbootsecurityauth%2Fservice%2FUserDetailsServiceImpl.java) class.\n\n```java\n@Service\npublic class UserDetailsServiceImpl implements UserDetailsService {\n\n  private final UserRepository userRepository;\n\n  public UserDetailsServiceImpl(UserRepository userRepository) {\n    this.userRepository = userRepository;\n  }\n\n  @Override\n  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {\n    AppUser appUser = userRepository.findByUsername(username)\n            .orElseThrow(() -\u003e new UsernameNotFoundException(\"Username not found\"));\n    return new User(appUser.getUsername(), appUser.getPassword(), mapRolesToAuthorities(appUser.getRoles()));\n  }\n\n  ...\n}\n```\n\n### JwtAuthorizationFilter\n\nThe JwtAuthorizationFilter is responsible for processing the JWT token from the request header. It extracts the token, validates it, and sets the authentication in the Security Context.\n\nThe JwtAuthorizationFilter is implemented in the [JwtAuthorizationFilter.java](src%2Fmain%2Fjava%2Fcom%2Fexample%2Fspringbootsecurityauth%2Fsecurity%2FJwtAuthorizationFilter.java) class.\n\n## Security Exception Handling\n\nIn this project, we have two classes to handle exceptions thrown during the authentication process. They are specified in the `SecurityFilterChain` configuration.\n\n### JwtAuthenticationEntryPoint\n\nThis class is responsible for handling exceptions thrown during the authentication process. It is used when the user is not authenticated.\n\n### AccessDeniedHandlerJwt\n\nThis class is responsible for handling exceptions thrown when the user is authenticated but does not have the required authorities to access the endpoint.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrecaiado%2Fspring-boot-security-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrecaiado%2Fspring-boot-security-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrecaiado%2Fspring-boot-security-auth/lists"}