├── .github ├── dependabot.yml └── workflows │ └── maven.yml ├── .gitignore ├── README.md ├── Spring Boot Security OAuth Example.postman_collection.json ├── img ├── auth.png ├── body.png ├── header.png ├── noauth.png └── oauth.png ├── pom.xml └── src └── main ├── java └── com │ └── hendisantika │ ├── Application.java │ ├── config │ ├── AuthorizationServerConfig.java │ ├── ResourceServerConfig.java │ └── SecurityConfig.java │ ├── controller │ └── UserController.java │ ├── dao │ └── UserDao.java │ ├── model │ └── User.java │ └── service │ ├── UserService.java │ └── impl │ └── UserServiceImpl.java └── resources ├── application.properties └── db └── migration └── V1.0.0.2018101901__Init_Schema_Data.sql /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: '21:00' 8 | timezone: Asia/Jakarta 9 | open-pull-requests-limit: 10 10 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "master" ] 14 | pull_request: 15 | branches: [ "master" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 21 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: '21' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | run: mvn -B package --file pom.xml 32 | 33 | # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive 34 | - name: Update dependency graph 35 | uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/ 3 | target 4 | src/test/ 5 | spring-boot-security-oauth2-example.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot Security OAuth Example 2 | 3 | #### Securing REST API with Spring Security OAuth2 4 | 5 | To run this repo, please follow these command : 6 | 7 | 1. Paste this command to your terminal 8 | 9 | `mvn clean spring-boot:run` 10 | 11 | 2. Launch POSTMAN to generate TOKEN 12 | 13 | ![Authorization Tab](img/auth.png "Authorization Tab") 14 | 15 | ![Header Tab](img/header.png "Header Tab") 16 | 17 | ![Body Tab](img/body.png "Body Tab") 18 | 19 | 3. Accessing without Token 20 | 21 | ![Accessing without Token](img/noauth.png "Accessing without Token") 22 | 23 | 4. Accessing Resource With Token 24 | 25 | ![Accessing Resource with Token](img/oauth.png "Accessing Resource with Token") 26 | -------------------------------------------------------------------------------- /Spring Boot Security OAuth Example.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "d42d2758-d8d4-4732-bbee-4f0fd349bdd4", 4 | "name": "Spring Boot Security OAuth Example", 5 | "description": "Spring Boot Security OAuth Example", 6 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 7 | }, 8 | "item": [ 9 | { 10 | "name": "Generate Token", 11 | "request": { 12 | "auth": { 13 | "type": "basic", 14 | "basic": [ 15 | { 16 | "key": "password", 17 | "value": "hendi-secret", 18 | "type": "string" 19 | }, 20 | { 21 | "key": "username", 22 | "value": "hendi-client", 23 | "type": "string" 24 | } 25 | ] 26 | }, 27 | "method": "POST", 28 | "header": [ 29 | { 30 | "key": "Accept", 31 | "value": "application/json", 32 | "type": "text" 33 | }, 34 | { 35 | "key": "Content-Type", 36 | "name": "Content-Type", 37 | "value": "application/x-www-form-urlencoded", 38 | "type": "text" 39 | } 40 | ], 41 | "body": { 42 | "mode": "urlencoded", 43 | "urlencoded": [ 44 | { 45 | "key": "username", 46 | "value": "hendi", 47 | "type": "text" 48 | }, 49 | { 50 | "key": "password", 51 | "value": "password", 52 | "type": "text" 53 | }, 54 | { 55 | "key": "grant_type", 56 | "value": "password", 57 | "type": "text" 58 | } 59 | ] 60 | }, 61 | "url": { 62 | "raw": "http://localhost:8080/oauth/token", 63 | "protocol": "http", 64 | "host": [ 65 | "localhost" 66 | ], 67 | "port": "8080", 68 | "path": [ 69 | "oauth", 70 | "token" 71 | ] 72 | }, 73 | "description": "Generate Token" 74 | }, 75 | "response": [] 76 | }, 77 | { 78 | "name": "Accessing Without Token", 79 | "request": { 80 | "method": "GET", 81 | "header": [], 82 | "url": { 83 | "raw": "http://localhost:8080/users/user", 84 | "protocol": "http", 85 | "host": [ 86 | "localhost" 87 | ], 88 | "port": "8080", 89 | "path": [ 90 | "users", 91 | "user" 92 | ] 93 | }, 94 | "description": "Accessing Without Token" 95 | }, 96 | "response": [] 97 | }, 98 | { 99 | "name": "Accessing With Token", 100 | "request": { 101 | "method": "GET", 102 | "header": [], 103 | "url": { 104 | "raw": "http://localhost:8080/users/user?access_token=05369009-d0e3-4d6d-aad9-ae7be41d707f", 105 | "protocol": "http", 106 | "host": [ 107 | "localhost" 108 | ], 109 | "port": "8080", 110 | "path": [ 111 | "users", 112 | "user" 113 | ], 114 | "query": [ 115 | { 116 | "key": "access_token", 117 | "value": "05369009-d0e3-4d6d-aad9-ae7be41d707f" 118 | } 119 | ] 120 | }, 121 | "description": "Accessing With Token" 122 | }, 123 | "response": [] 124 | } 125 | ] 126 | } -------------------------------------------------------------------------------- /img/auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendisantika/spring-boot-security-oauth2-example/e086151bf9769ae5e2539d189429ef639d923cab/img/auth.png -------------------------------------------------------------------------------- /img/body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendisantika/spring-boot-security-oauth2-example/e086151bf9769ae5e2539d189429ef639d923cab/img/body.png -------------------------------------------------------------------------------- /img/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendisantika/spring-boot-security-oauth2-example/e086151bf9769ae5e2539d189429ef639d923cab/img/header.png -------------------------------------------------------------------------------- /img/noauth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendisantika/spring-boot-security-oauth2-example/e086151bf9769ae5e2539d189429ef639d923cab/img/noauth.png -------------------------------------------------------------------------------- /img/oauth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hendisantika/spring-boot-security-oauth2-example/e086151bf9769ae5e2539d189429ef639d923cab/img/oauth.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.hendisantika 8 | spring-boot-security-oauth2-example 9 | 1.0.0 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 3.5.0 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-web 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-jpa 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-security 29 | 30 | 31 | org.springframework.security.oauth 32 | spring-security-oauth2 33 | 2.5.2.RELEASE 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | com.mysql 53 | mysql-connector-j 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.apache.commons 62 | commons-dbcp2 63 | 2.13.0 64 | 65 | 66 | org.projectlombok 67 | lombok 68 | 69 | 70 | org.flywaydb 71 | flyway-core 72 | 73 | 74 | 75 | 76 | 21 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/Application.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Created by IntelliJ IDEA. 8 | * Project : spring-boot-security-oauth2-example 9 | * User: hendisantika 10 | * Email: hendisantika@gmail.com 11 | * Telegram : @hendisantika34 12 | * Date: 31/12/17 13 | * Time: 15.43 14 | * To change this template use File | Settings | File Templates. 15 | */ 16 | 17 | @SpringBootApplication 18 | public class Application { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(Application.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/config/AuthorizationServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.authentication.AuthenticationManager; 6 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 7 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 9 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 10 | import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; 11 | import org.springframework.security.oauth2.provider.token.TokenStore; 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * Project : spring-boot-security-oauth2-example 16 | * User: hendisantika 17 | * Email: hendisantika@gmail.com 18 | * Telegram : @hendisantika34 19 | * Date: 31/12/17 20 | * Time: 16.06 21 | * To change this template use File | Settings | File Templates. 22 | */ 23 | 24 | @Configuration 25 | @EnableAuthorizationServer 26 | public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 27 | 28 | static final String CLIENT_ID = "hendi-client"; 29 | static final String CLIENT_SECRET = "hendi-secret"; 30 | static final String GRANT_TYPE = "password"; 31 | static final String SCOPE_READ = "read"; 32 | static final String SCOPE_WRITE = "write"; 33 | static final int ACCESS_TOKEN_VALIDITY_SECONDS = 60 * 60; 34 | static final int REFRESH_TOKEN_VALIDITY_SECONDS = 6 * 60 * 60; 35 | 36 | @Autowired 37 | private TokenStore tokenStore; 38 | 39 | @Autowired 40 | private UserApprovalHandler userApprovalHandler; 41 | 42 | @Autowired 43 | private AuthenticationManager authenticationManager; 44 | 45 | @Override 46 | public void configure(ClientDetailsServiceConfigurer configurer) throws Exception { 47 | 48 | configurer 49 | .inMemory() 50 | .withClient(CLIENT_ID) 51 | .secret(CLIENT_SECRET) 52 | .authorizedGrantTypes(GRANT_TYPE) 53 | .scopes(SCOPE_READ, SCOPE_WRITE) 54 | .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS). 55 | refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS); 56 | } 57 | 58 | @Override 59 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) { 60 | endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler) 61 | .authenticationManager(authenticationManager); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/config/ResourceServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 7 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; 8 | import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * Project : spring-boot-security-oauth2-example 13 | * User: hendisantika 14 | * Email: hendisantika@gmail.com 15 | * Telegram : @hendisantika34 16 | * Date: 31/12/17 17 | * Time: 16.03 18 | * To change this template use File | Settings | File Templates. 19 | */ 20 | 21 | @Configuration 22 | @EnableResourceServer 23 | public class ResourceServerConfig extends ResourceServerConfigurerAdapter { 24 | 25 | private static final String RESOURCE_ID = "resource_id"; 26 | 27 | @Override 28 | public void configure(ResourceServerSecurityConfigurer resources) { 29 | resources.resourceId(RESOURCE_ID).stateless(false); 30 | } 31 | 32 | @Override 33 | public void configure(HttpSecurity http) throws Exception { 34 | http. 35 | anonymous().disable() 36 | .authorizeRequests() 37 | .requestMatchers("/users/**").access("hasRole('ADMIN')") 38 | .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.config; 2 | 3 | import jakarta.annotation.Resource; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.authentication.AuthenticationManager; 9 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 10 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 13 | import org.springframework.security.core.userdetails.UserDetailsService; 14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 15 | import org.springframework.security.oauth2.provider.ClientDetailsService; 16 | import org.springframework.security.oauth2.provider.approval.ApprovalStore; 17 | import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; 18 | import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler; 19 | import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; 20 | import org.springframework.security.oauth2.provider.token.TokenStore; 21 | import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; 22 | import org.springframework.security.web.SecurityFilterChain; 23 | import org.springframework.web.cors.CorsConfiguration; 24 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 25 | import org.springframework.web.filter.CorsFilter; 26 | 27 | 28 | /** 29 | * Created by IntelliJ IDEA. 30 | * Project : spring-boot-security-oauth2-example 31 | * User: hendisantika 32 | * Email: hendisantika@gmail.com 33 | * Telegram : @hendisantika34 34 | * Date: 31/12/17 35 | * Time: 16.01 36 | * To change this template use File | Settings | File Templates. 37 | */ 38 | 39 | @Configuration 40 | @EnableWebSecurity 41 | @EnableGlobalMethodSecurity(prePostEnabled = true) 42 | public class SecurityConfig { 43 | 44 | @Resource(name = "userService") 45 | private UserDetailsService userDetailsService; 46 | 47 | @Autowired 48 | private ClientDetailsService clientDetailsService; 49 | 50 | @Bean 51 | public AuthenticationManager authenticationManagerBean() throws Exception { 52 | return authenticationManagerBean(); 53 | } 54 | 55 | @Autowired 56 | public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { 57 | auth.userDetailsService(userDetailsService) 58 | .passwordEncoder(encoder()); 59 | } 60 | 61 | @Bean 62 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 63 | http 64 | .csrf().disable() 65 | .anonymous().disable() 66 | .authorizeRequests() 67 | .requestMatchers("/api-docs/**").permitAll(); 68 | return http.build(); 69 | } 70 | 71 | @Bean 72 | public TokenStore tokenStore() { 73 | return new InMemoryTokenStore(); 74 | } 75 | 76 | @Bean 77 | @Autowired 78 | public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) { 79 | TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler(); 80 | handler.setTokenStore(tokenStore); 81 | handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService)); 82 | handler.setClientDetailsService(clientDetailsService); 83 | return handler; 84 | } 85 | 86 | @Bean 87 | @Autowired 88 | public ApprovalStore approvalStore(TokenStore tokenStore) { 89 | TokenApprovalStore store = new TokenApprovalStore(); 90 | store.setTokenStore(tokenStore); 91 | return store; 92 | } 93 | 94 | @Bean 95 | public BCryptPasswordEncoder encoder() { 96 | return new BCryptPasswordEncoder(); 97 | } 98 | 99 | @Bean 100 | public FilterRegistrationBean corsFilter() { 101 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 102 | CorsConfiguration config = new CorsConfiguration(); 103 | config.setAllowCredentials(true); 104 | config.addAllowedOrigin("*"); 105 | config.addAllowedHeader("*"); 106 | config.addAllowedMethod("*"); 107 | source.registerCorsConfiguration("/**", config); 108 | FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); 109 | bean.setOrder(0); 110 | return bean; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.controller; 2 | 3 | import com.hendisantika.model.User; 4 | import com.hendisantika.service.UserService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by IntelliJ IDEA. 12 | * Project : spring-boot-security-oauth2-example 13 | * User: hendisantika 14 | * Email: hendisantika@gmail.com 15 | * Telegram : @hendisantika34 16 | * Date: 10/01/18 17 | * Time: 16.06 18 | * To change this template use File | Settings | File Templates. 19 | */ 20 | 21 | @RestController 22 | @RequestMapping("/users") 23 | public class UserController { 24 | 25 | @Autowired 26 | private UserService userService; 27 | 28 | @RequestMapping(value = "/user", method = RequestMethod.GET) 29 | public List listUser() { 30 | return userService.findAll(); 31 | } 32 | 33 | @RequestMapping(value = "/user", method = RequestMethod.POST) 34 | public User create(@RequestBody User user) { 35 | return userService.save(user); 36 | } 37 | 38 | @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) 39 | public String delete(@PathVariable(value = "id") Long id) { 40 | userService.delete(id); 41 | return "success"; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.dao; 2 | 3 | import com.hendisantika.model.User; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * Created by IntelliJ IDEA. 9 | * Project : spring-boot-security-oauth2-example 10 | * User: hendisantika 11 | * Email: hendisantika@gmail.com 12 | * Telegram : @hendisantika34 13 | * Date: 31/12/17 14 | * Time: 15.48 15 | * To change this template use File | Settings | File Templates. 16 | */ 17 | 18 | 19 | @Repository 20 | public interface UserDao extends CrudRepository { 21 | User findByUsername(String username); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/model/User.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import jakarta.persistence.Column; 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.GeneratedValue; 7 | import jakarta.persistence.GenerationType; 8 | import jakarta.persistence.Id; 9 | import jakarta.persistence.Table; 10 | import lombok.Data; 11 | 12 | 13 | /** 14 | * Created by IntelliJ IDEA. 15 | * Project : spring-boot-security-oauth2-example 16 | * User: hendisantika 17 | * Email: hendisantika@gmail.com 18 | * Telegram : @hendisantika34 19 | * Date: 31/12/17 20 | * Time: 15.45 21 | * To change this template use File | Settings | File Templates. 22 | */ 23 | 24 | @Data 25 | @Entity 26 | @Table(name = "tbl_user") 27 | public class User { 28 | 29 | @Id 30 | @GeneratedValue(strategy = GenerationType.IDENTITY) 31 | private long id; 32 | 33 | @Column 34 | private String username; 35 | 36 | @Column 37 | @JsonIgnore 38 | private String password; 39 | 40 | @Column 41 | private long salary; 42 | 43 | @Column 44 | private int age; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.service; 2 | 3 | import com.hendisantika.model.User; 4 | 5 | import java.util.List; 6 | 7 | 8 | /** 9 | * Created by IntelliJ IDEA. 10 | * Project : spring-boot-security-oauth2-example 11 | * User: hendisantika 12 | * Email: hendisantika@gmail.com 13 | * Telegram : @hendisantika34 14 | * Date: 31/12/17 15 | * Time: 15.52 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | 19 | public interface UserService { 20 | 21 | User save(User user); 22 | 23 | List findAll(); 24 | 25 | void delete(long id); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/hendisantika/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.hendisantika.service.impl; 2 | 3 | import com.hendisantika.dao.UserDao; 4 | import com.hendisantika.model.User; 5 | import com.hendisantika.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.core.userdetails.UserDetailsService; 10 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by IntelliJ IDEA. 19 | * Project : spring-boot-security-oauth2-example 20 | * User: hendisantika 21 | * Email: hendisantika@gmail.com 22 | * Telegram : @hendisantika34 23 | * Date: 31/12/17 24 | * Time: 15.55 25 | * To change this template use File | Settings | File Templates. 26 | */ 27 | 28 | @Service(value = "userService") 29 | public class UserServiceImpl implements UserDetailsService, UserService { 30 | 31 | @Autowired 32 | private UserDao userDao; 33 | 34 | public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { 35 | User user = userDao.findByUsername(userId); 36 | if (user == null) { 37 | throw new UsernameNotFoundException("Invalid username or password."); 38 | } 39 | return new org.springframework.security.core.userdetails.User(String.valueOf(user.getId()), user.getPassword(), getAuthority()); 40 | } 41 | 42 | private List getAuthority() { 43 | return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")); 44 | } 45 | 46 | public List findAll() { 47 | List list = new ArrayList<>(); 48 | userDao.findAll().iterator().forEachRemaining(list::add); 49 | return list; 50 | } 51 | 52 | @Override 53 | public void delete(long id) { 54 | userDao.deleteById(id); 55 | } 56 | 57 | @Override 58 | public User save(User user) { 59 | return userDao.save(user); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/oauth?createDatabaseIfNotExist=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Jakarta&useSSL=false 2 | spring.datasource.username=root 3 | spring.datasource.password=root 4 | spring.jpa.generate-ddl=true 5 | spring.jpa.show-sql=true 6 | spring.jpa.hibernate.ddl-auto=validate 7 | spring.jpa.properties.hibernate.format_sql=true 8 | spring.user.datasource.driver-class-name=com.mysql.jdbc.Driver 9 | security.oauth2.resource.filter-order=3 -------------------------------------------------------------------------------- /src/main/resources/db/migration/V1.0.0.2018101901__Init_Schema_Data.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE tbl_user ( 2 | id bigint(20) NOT NULL, 3 | username varchar(25) NOT NULL, 4 | password varchar(75) NOT NULL, 5 | salary bigint(10) NOT NULL, 6 | age int(2) NOT NULL, 7 | PRIMARY KEY (id) 8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 9 | 10 | INSERT INTO tbl_user (id, username, password, salary, age) VALUES (1, 'hendi', '$2a$04$I9Q2sDc4QGGg5WNTLmsz0.fvGv3OjoZyj81PrSFyGOqMphqfS2qKu', 3456, 33); 11 | INSERT INTO tbl_user (id, username, password, salary, age) VALUES (2, 'sasuke', '$2a$04$PCIX2hYrve38M7eOcqAbCO9UqjYg7gfFNpKsinAxh99nms9e.8HwK', 7823, 23); 12 | INSERT INTO tbl_user (id, username, password, salary, age) VALUES (3, 'naruto', '$2a$04$I9Q2sDc4QGGg5WNTLmsz0.fvGv3OjoZyj81PrSFyGOqMphqfS2qKu', 4234, 45); 13 | INSERT INTO tbl_user (id, username, password, salary, age) VALUES (4, 'sakura', '$2a$04$I9Q2sDc4QGGg5WNTLmsz0.fvGv3OjoZyj81PrSFyGOqMphqfS2qKu', 4234, 40); 14 | 15 | 16 | -- hendi / password 17 | -- sasuke / password 18 | -- naruto / password 19 | -- sakura / password --------------------------------------------------------------------------------