From 339540b90f597d78bc50af14345f5fe743723133 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Mon, 5 Feb 2018 02:11:49 +0900 Subject: [PATCH 1/6] [#2] Ready for log in with GitHub --- build.gradle | 1 + .../java/com/coduckfoilo/WebApplication.java | 91 ++++++++++++++++++- src/main/resources/application.yml | 9 ++ src/main/resources/templates/index.ftl | 12 +++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/index.ftl diff --git a/build.gradle b/build.gradle index 7b441d4..6a56e5b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ dependencies { compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.springframework.boot:spring-boot-starter-freemarker') compile('org.springframework.boot:spring-boot-starter-security') + compile('org.springframework.security.oauth:spring-security-oauth2') compile('org.springframework.boot:spring-boot-starter-web') runtime('org.springframework.boot:spring-boot-devtools') runtime('com.h2database:h2') diff --git a/src/main/java/com/coduckfoilo/WebApplication.java b/src/main/java/com/coduckfoilo/WebApplication.java index 29ac5bc..665ea20 100644 --- a/src/main/java/com/coduckfoilo/WebApplication.java +++ b/src/main/java/com/coduckfoilo/WebApplication.java @@ -1,12 +1,101 @@ package com.coduckfoilo; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; +import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.client.OAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter; +import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.filter.CompositeFilter; + +import javax.servlet.Filter; +import java.util.ArrayList; +import java.util.List; @SpringBootApplication -public class WebApplication { +@EnableOAuth2Client +@Controller +public class WebApplication extends WebSecurityConfigurerAdapter { + + @Autowired + OAuth2ClientContext oauth2ClientContext; public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } + + @RequestMapping("/") + public String index() { + return "index"; + } + + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/**") + .authorizeRequests() + .antMatchers("/", "/login**", "/webjars/**") + .permitAll() + .anyRequest() + .authenticated() + .and().logout().logoutSuccessUrl("/").permitAll() + .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) + .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); + } + + @Bean + public FilterRegistrationBean oauth2ClientFilterRegistration( + OAuth2ClientContextFilter filter) { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(filter); + registration.setOrder(-100); + return registration; + } + + private Filter ssoFilter() { + + CompositeFilter filter = new CompositeFilter(); + List filters = new ArrayList<>(); + + OAuth2ClientAuthenticationProcessingFilter githubFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github"); + OAuth2RestTemplate githubTemplate = new OAuth2RestTemplate(github(), oauth2ClientContext); + githubFilter.setRestTemplate(githubTemplate); + UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), github().getClientId()); + tokenServices.setRestTemplate(githubTemplate); + githubFilter.setTokenServices(tokenServices); + + filters.add(githubFilter); + + filter.setFilters(filters); + return filter; + } + + @Bean + @ConfigurationProperties("github.client") + public AuthorizationCodeResourceDetails github() { + return new AuthorizationCodeResourceDetails(); + } + + @Bean + @ConfigurationProperties("github.resource") + public ResourceServerProperties githubResource() { + return new ResourceServerProperties(); + } + + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e69de29..806ef6c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -0,0 +1,9 @@ +github: + client: + clientId: ${GITHUB_OAUTH_APP_ID} + clientSecret: ${GITHUB_OAUTH_APP_PW} + accessTokenUri: https://github.com/login/oauth/access_token + userAuthorizationUri: https://github.com/login/oauth/authorize + clientAuthenticationScheme: form + resource: + userInfoUri: https://api.github.com/user \ No newline at end of file diff --git a/src/main/resources/templates/index.ftl b/src/main/resources/templates/index.ftl new file mode 100644 index 0000000..91d4c8d --- /dev/null +++ b/src/main/resources/templates/index.ftl @@ -0,0 +1,12 @@ + + + + + GitHub Login + + +
+ With Github: click here +
+ + From e9cb65d420aa1cb993062d2a96d646eab4ac96a2 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Thu, 15 Feb 2018 15:06:02 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[#1]=20localhost:8080/users/{githubName}=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9C=A0=EC=A0=80=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coduckfoilo/domain/UserController.java | 50 +++++++++++++++++++ .../com/coduckfoilo/domain/user/User.java | 3 ++ 2 files changed, 53 insertions(+) create mode 100644 src/main/java/com/coduckfoilo/domain/UserController.java diff --git a/src/main/java/com/coduckfoilo/domain/UserController.java b/src/main/java/com/coduckfoilo/domain/UserController.java new file mode 100644 index 0000000..3da0d52 --- /dev/null +++ b/src/main/java/com/coduckfoilo/domain/UserController.java @@ -0,0 +1,50 @@ +package com.coduckfoilo.domain; + +import com.coduckfoilo.domain.user.User; +import com.coduckfoilo.domain.user.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import java.util.List; +import java.util.Map; + +/** + * IDE : IntelliJ IDEA + * Created by minho on 2018. 2. 10.. + */ + +@RestController +@RequestMapping(value = "/users") +public class UserController { + + @Autowired + private UserRepository userRepository; + + @RequestMapping(value = "/{name}", method = RequestMethod.GET) + public ResponseEntity getUser(@PathVariable("name") String name) { + // Git Hub API를 사용하기 위한 작업, Util class 로 대체할 예정 + RestTemplate restTemplate = new RestTemplate(); + + SecurityContextHolder.getContext().getAuthentication().getDetails(); + String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); + + MultiValueMap headers = new LinkedMultiValueMap<>(); + headers.set(HttpHeaders.AUTHORIZATION, "token " + token); + HttpEntity httpEntity = new HttpEntity(headers); + + ResponseEntity responseEntity = restTemplate.getForEntity("https://api.github.com/users/" + name, Map.class, httpEntity); + return responseEntity; + } +} diff --git a/src/main/java/com/coduckfoilo/domain/user/User.java b/src/main/java/com/coduckfoilo/domain/user/User.java index 178bf2a..3387511 100644 --- a/src/main/java/com/coduckfoilo/domain/user/User.java +++ b/src/main/java/com/coduckfoilo/domain/user/User.java @@ -24,4 +24,7 @@ public class User { @Column(unique = true) private String email; + + @Column(unique = true) + private String githubName; } From a12a831e650f77eff4d94dcbdbe33d3a308c3582 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Sat, 17 Feb 2018 14:47:23 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[#1]=20github=20api=20library=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 6a56e5b..ad059e7 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ dependencies { compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.security.oauth:spring-security-oauth2') compile('org.springframework.boot:spring-boot-starter-web') + compile('org.kohsuke:github-ap:1.92') runtime('org.springframework.boot:spring-boot-devtools') runtime('com.h2database:h2') runtime('mysql:mysql-connector-java') From 0681d3c25e33eb7cd561dfe6bc92b649d103cd13 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Sat, 17 Feb 2018 14:52:13 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[#1]=20user=20=EC=A0=95=EB=B3=B4=20url=20?= =?UTF-8?q?=EC=9D=84=20/users/{name}=20=EC=97=90=EC=84=9C=20/{name}=20?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coduckfoilo/domain/UserController.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/coduckfoilo/domain/UserController.java b/src/main/java/com/coduckfoilo/domain/UserController.java index 3da0d52..3672084 100644 --- a/src/main/java/com/coduckfoilo/domain/UserController.java +++ b/src/main/java/com/coduckfoilo/domain/UserController.java @@ -1,7 +1,10 @@ package com.coduckfoilo.domain; +import com.coduckfoilo.domain.project.Project; import com.coduckfoilo.domain.user.User; import com.coduckfoilo.domain.user.UserRepository; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -26,25 +29,39 @@ */ @RestController -@RequestMapping(value = "/users") +@RequestMapping(value = "/") public class UserController { @Autowired private UserRepository userRepository; @RequestMapping(value = "/{name}", method = RequestMethod.GET) - public ResponseEntity getUser(@PathVariable("name") String name) { + public ResponseEntity getUser(@PathVariable("name") String name) { // Git Hub API를 사용하기 위한 작업, Util class 로 대체할 예정 RestTemplate restTemplate = new RestTemplate(); - - SecurityContextHolder.getContext().getAuthentication().getDetails(); String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); MultiValueMap headers = new LinkedMultiValueMap<>(); headers.set(HttpHeaders.AUTHORIZATION, "token " + token); HttpEntity httpEntity = new HttpEntity(headers); - ResponseEntity responseEntity = restTemplate.getForEntity("https://api.github.com/users/" + name, Map.class, httpEntity); - return responseEntity; + ResponseEntity response = restTemplate.getForEntity("https://api.github.com/users/" + name, String.class, httpEntity); + + return response; } +// +// @RequestMapping(value = "/{name}/projects", method = RequestMethod.GET) +// public ResponseEntity getProjects(@PathVariable("name") String name) { +// // Git Hub API를 사용하기 위한 작업, Util class 로 대체할 예정 +// RestTemplate restTemplate = new RestTemplate(); +// String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); +// +// MultiValueMap headers = new LinkedMultiValueMap<>(); +// headers.set(HttpHeaders.AUTHORIZATION, "token " + token); +// HttpEntity httpEntity = new HttpEntity(headers); +// +// ResponseEntity response = restTemplate.getForEntity("https://api.github.com/users/" + name + "/repos", String.class, httpEntity); +// +// return response; +// } } From 87df369e199af0e3cda1d96103ddcabbbd0f2608 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Sun, 25 Feb 2018 14:27:36 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[#1]=20github=20api=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ad059e7..bddea14 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.security.oauth:spring-security-oauth2') compile('org.springframework.boot:spring-boot-starter-web') - compile('org.kohsuke:github-ap:1.92') + compile('org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5') runtime('org.springframework.boot:spring-boot-devtools') runtime('com.h2database:h2') runtime('mysql:mysql-connector-java') From 281ba6a856e118851d1e23c982472d5c04d74171 Mon Sep 17 00:00:00 2001 From: minomi <5minhominho@gmail.com> Date: Sun, 25 Feb 2018 14:28:34 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[#1]=20id=20,=20name,=20email=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coduckfoilo/domain/UserController.java | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/coduckfoilo/domain/UserController.java b/src/main/java/com/coduckfoilo/domain/UserController.java index 3672084..322582d 100644 --- a/src/main/java/com/coduckfoilo/domain/UserController.java +++ b/src/main/java/com/coduckfoilo/domain/UserController.java @@ -5,6 +5,13 @@ import com.coduckfoilo.domain.user.UserRepository; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; +import org.eclipse.egit.github.core.Repository; +import org.eclipse.egit.github.core.client.GitHubClient; +import org.eclipse.egit.github.core.client.GitHubRequest; +import org.eclipse.egit.github.core.client.GitHubResponse; +import org.eclipse.egit.github.core.service.GitHubService; +import org.eclipse.egit.github.core.service.RepositoryService; +import org.eclipse.egit.github.core.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -19,7 +26,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; +import sun.reflect.annotation.ExceptionProxy; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -36,32 +45,26 @@ public class UserController { private UserRepository userRepository; @RequestMapping(value = "/{name}", method = RequestMethod.GET) - public ResponseEntity getUser(@PathVariable("name") String name) { + public String getUser(@PathVariable("name") String name) { // Git Hub API를 사용하기 위한 작업, Util class 로 대체할 예정 - RestTemplate restTemplate = new RestTemplate(); String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.set(HttpHeaders.AUTHORIZATION, "token " + token); - HttpEntity httpEntity = new HttpEntity(headers); + try { + GitHubClient gitHubClient = new GitHubClient(); + gitHubClient.setOAuth2Token(token); + UserService userService = new UserService(gitHubClient); - ResponseEntity response = restTemplate.getForEntity("https://api.github.com/users/" + name, String.class, httpEntity); + String email = userService.getUser(name).getEmail(); + int id = userService.getUser(name).getId(); + String gitHubName = userService.getUser(name).getName(); - return response; + return email + " " + id + " " + gitHubName; + + } catch (Exception e) { + e.printStackTrace(); + } + + return ""; } -// -// @RequestMapping(value = "/{name}/projects", method = RequestMethod.GET) -// public ResponseEntity getProjects(@PathVariable("name") String name) { -// // Git Hub API를 사용하기 위한 작업, Util class 로 대체할 예정 -// RestTemplate restTemplate = new RestTemplate(); -// String token = ((OAuth2AuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails()).getTokenValue(); -// -// MultiValueMap headers = new LinkedMultiValueMap<>(); -// headers.set(HttpHeaders.AUTHORIZATION, "token " + token); -// HttpEntity httpEntity = new HttpEntity(headers); -// -// ResponseEntity response = restTemplate.getForEntity("https://api.github.com/users/" + name + "/repos", String.class, httpEntity); -// -// return response; -// } + }