Skip to content

Commit fe806ac

Browse files
author
loic
committed
Added OAuth (github, google). Changed antMatcher to ROLE instead of authority
1 parent c81afac commit fe806ac

File tree

13 files changed

+349
-156
lines changed

13 files changed

+349
-156
lines changed

Poseiden-skeleton/pom.xml

Lines changed: 105 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,77 @@
1212
<artifactId>spring-boot-skeleton</artifactId>
1313
<version>0.0.1-SNAPSHOT</version>
1414
<name>spring-boot-skeleton</name>
15-
<description>Demo project for Spring Boot</description>
15+
<description>Spring Boot project for OpenClassrooms DA JAVA 7th project</description>
1616
<properties>
1717
<java.version>11</java.version>
18+
<!-- JaCoCo Properties -->
19+
<jacoco.version>0.8.6</jacoco.version>
20+
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
21+
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
22+
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
23+
<sonar.language>java</sonar.language>
1824
</properties>
1925
<dependencies>
26+
<!-- ******************************************************************* -->
27+
<!-- ************************* SPRING BOOT ***************************** -->
28+
<!-- ******************************************************************* -->
2029
<dependency>
2130
<groupId>org.springframework.boot</groupId>
22-
<artifactId>spring-boot-starter-actuator</artifactId>
31+
<artifactId>spring-boot-starter-web</artifactId>
2332
</dependency>
2433
<dependency>
2534
<groupId>org.springframework.boot</groupId>
26-
<artifactId>spring-boot-starter-data-jpa</artifactId>
35+
<artifactId>spring-boot-starter-actuator</artifactId>
2736
</dependency>
2837
<dependency>
2938
<groupId>org.springframework.boot</groupId>
30-
<artifactId>spring-boot-starter-security</artifactId>
39+
<artifactId>spring-boot-devtools</artifactId>
40+
<scope>runtime</scope>
41+
<optional>true</optional>
3142
</dependency>
43+
<!-- ***************************************************************** -->
44+
<!-- ************************* THYMELEAF ***************************** -->
45+
<!-- ***************************************************************** -->
3246
<dependency>
3347
<groupId>org.springframework.boot</groupId>
3448
<artifactId>spring-boot-starter-thymeleaf</artifactId>
3549
</dependency>
3650
<dependency>
37-
<groupId>org.springframework.boot</groupId>
38-
<artifactId>spring-boot-starter-validation</artifactId>
51+
<groupId>org.thymeleaf.extras</groupId>
52+
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
3953
</dependency>
54+
<!-- ***************************************************************** -->
55+
<!-- *************************** TESTS ******************************* -->
56+
<!-- ***************************************************************** -->
4057
<dependency>
4158
<groupId>org.springframework.boot</groupId>
42-
<artifactId>spring-boot-starter-web</artifactId>
59+
<artifactId>spring-boot-starter-test</artifactId>
60+
<scope>test</scope>
4361
</dependency>
4462
<dependency>
45-
<groupId>org.thymeleaf.extras</groupId>
46-
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
63+
<groupId>org.springframework.security</groupId>
64+
<artifactId>spring-security-test</artifactId>
65+
<scope>test</scope>
4766
</dependency>
48-
4967
<dependency>
50-
<groupId>org.hibernate</groupId>
51-
<artifactId>hibernate-validator</artifactId>
52-
<version>6.0.10.Final</version>
68+
<groupId>org.jacoco</groupId>
69+
<artifactId>jacoco-maven-plugin</artifactId>
70+
<version>${jacoco.version}</version>
5371
</dependency>
54-
72+
<!-- ***************************************************************** -->
73+
<!-- ************************* SECURITY ****************************** -->
74+
<!-- ***************************************************************** -->
5575
<dependency>
5676
<groupId>org.springframework.boot</groupId>
57-
<artifactId>spring-boot-devtools</artifactId>
58-
<scope>runtime</scope>
59-
<optional>true</optional>
77+
<artifactId>spring-boot-starter-security</artifactId>
78+
</dependency>
79+
<dependency>
80+
<groupId>org.springframework.security</groupId>
81+
<artifactId>spring-security-oauth2-client</artifactId>
6082
</dependency>
83+
<!-- ***************************************************************** -->
84+
<!-- ************************* DATABASE ****************************** -->
85+
<!-- ***************************************************************** -->
6186
<dependency>
6287
<groupId>com.h2database</groupId>
6388
<artifactId>h2</artifactId>
@@ -70,38 +95,92 @@
7095
</dependency>
7196
<dependency>
7297
<groupId>org.springframework.boot</groupId>
73-
<artifactId>spring-boot-starter-test</artifactId>
74-
<scope>test</scope>
75-
</dependency>
76-
<dependency>
77-
<groupId>org.springframework.security</groupId>
78-
<artifactId>spring-security-test</artifactId>
79-
<scope>test</scope>
98+
<artifactId>spring-boot-starter-data-jpa</artifactId>
8099
</dependency>
100+
<!-- ****************************************************************** -->
101+
<!-- ************************* VALIDATION ***************************** -->
102+
<!-- ****************************************************************** -->
81103
<dependency>
82-
<groupId>com.fasterxml.jackson.datatype</groupId>
83-
<artifactId>jackson-datatype-jsr310</artifactId>
104+
<groupId>org.springframework.boot</groupId>
105+
<artifactId>spring-boot-starter-validation</artifactId>
84106
</dependency>
85107
<dependency>
86108
<groupId>org.passay</groupId>
87109
<artifactId>passay</artifactId>
88110
<version>1.0</version>
89111
</dependency>
112+
<dependency>
113+
<groupId>org.hibernate.validator</groupId>
114+
<artifactId>hibernate-validator</artifactId>
115+
<version>6.0.10.Final</version>
116+
</dependency>
90117
<dependency>
91118
<groupId>com.google.guava</groupId>
92119
<artifactId>guava</artifactId>
93120
<version>28.2-jre</version>
94121
</dependency>
122+
<dependency>
123+
<groupId>com.fasterxml.jackson.datatype</groupId>
124+
<artifactId>jackson-datatype-jsr310</artifactId>
125+
</dependency>
126+
<dependency>
127+
<groupId>org.apache.maven.plugins</groupId>
128+
<artifactId>maven-site-plugin</artifactId>
129+
<version>3.9.0</version>
130+
</dependency>
95131
</dependencies>
96132

133+
<!-- ************************************************************* -->
134+
<!-- ************************* BUILD ***************************** -->
135+
<!-- ************************************************************* -->
97136
<build>
98137
<plugins>
99138
<plugin>
100139
<groupId>org.springframework.boot</groupId>
101140
<artifactId>spring-boot-maven-plugin</artifactId>
102141
<version>${project.parent.version}</version>
103142
</plugin>
143+
<plugin>
144+
<groupId>org.jacoco</groupId>
145+
<artifactId>jacoco-maven-plugin</artifactId>
146+
<version>${jacoco.version}</version>
147+
<configuration>
148+
<excludes>
149+
<exclude>com/nnk/springboot/dto/*</exclude>
150+
<exclude>**/config/*</exclude>
151+
<exclude>com/nnk/springboot/domain/*</exclude>
152+
</excludes>
153+
</configuration>
154+
<executions>
155+
<execution>
156+
<id>jacoco-initialize</id>
157+
<goals>
158+
<goal>prepare-agent</goal>
159+
</goals>
160+
</execution>
161+
<execution>
162+
<id>jacoco-site</id>
163+
<phase>package</phase>
164+
<goals>
165+
<goal>report</goal>
166+
</goals>
167+
</execution>
168+
</executions>
169+
</plugin>
104170
</plugins>
105171
</build>
106172

173+
<!-- ***************************************************************** -->
174+
<!-- ************************* REPORTING ***************************** -->
175+
<!-- ***************************************************************** -->
176+
<reporting>
177+
<plugins>
178+
<plugin>
179+
<groupId>org.apache.maven.plugins</groupId>
180+
<artifactId>maven-project-info-reports-plugin</artifactId>
181+
<version>2.9</version>
182+
</plugin>
183+
</plugins>
184+
</reporting>
185+
107186
</project>

Poseiden-skeleton/src/main/java/com/nnk/springboot/config/SecurityConfiguration.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package com.nnk.springboot.config;
22

3-
import com.nnk.springboot.services.UserDetailsServiceImpl;
43
import org.springframework.beans.factory.annotation.Autowired;
54
import org.springframework.context.annotation.Bean;
65
import org.springframework.context.annotation.Configuration;
76
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
8-
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
97
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
109
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
1110
import org.springframework.security.core.userdetails.UserDetailsService;
1211
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1312
import org.springframework.security.crypto.password.PasswordEncoder;
1413

1514
@Configuration
15+
@EnableWebSecurity
1616
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
1717

1818
@Autowired
@@ -27,12 +27,10 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
2727
protected void configure(HttpSecurity http) throws Exception {
2828

2929
http
30-
.formLogin().defaultSuccessUrl("/bidList/list")
31-
.failureUrl("/app/error").permitAll()
32-
.and()
30+
3331
.authorizeRequests()
3432
// permit all
35-
.antMatchers("/403")
33+
.antMatchers("/error")
3634
.permitAll()
3735
// user
3836
.antMatchers(
@@ -41,13 +39,15 @@ protected void configure(HttpSecurity http) throws Exception {
4139
"/ruleName/**",
4240
"/rating/**",
4341
"/trade/**")
44-
.hasAnyAuthority("USER","ADMIN")
42+
.hasAnyRole("USER", "ADMIN")
4543
//admin
4644
.antMatchers("/user/**")
47-
.hasAuthority("ADMIN")
48-
.and()
49-
.exceptionHandling()
50-
.accessDeniedPage("/403")
45+
.hasRole("ADMIN")
46+
.and()
47+
.formLogin()
48+
.and()
49+
.oauth2Login()
50+
5151
;
5252
}
5353

Poseiden-skeleton/src/main/java/com/nnk/springboot/controllers/LoginController.java

Lines changed: 97 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,126 @@
44
import org.apache.logging.log4j.LogManager;
55
import org.apache.logging.log4j.Logger;
66
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
8+
import org.springframework.security.core.userdetails.User;
9+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
10+
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
11+
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
12+
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
13+
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
14+
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
15+
import org.springframework.security.oauth2.core.user.OAuth2User;
716
import org.springframework.stereotype.Controller;
817
import org.springframework.ui.Model;
918
import org.springframework.web.bind.annotation.GetMapping;
10-
import org.springframework.web.bind.annotation.RequestMapping;
19+
import org.springframework.web.bind.annotation.ResponseBody;
1120
import org.springframework.web.servlet.ModelAndView;
1221

22+
import java.security.Principal;
23+
import java.util.Map;
24+
1325
@Controller
14-
@RequestMapping("/app")
1526
public class LoginController {
1627

17-
@Autowired
18-
private UserRepository userRepository;
19-
28+
private final UserRepository userRepository;
29+
private final OAuth2AuthorizedClientService authorizedClientService;
2030
private final Logger log = LogManager.getLogger(getClass().getName());
2131

22-
@GetMapping("login")
23-
public ModelAndView login() {
24-
ModelAndView mav = new ModelAndView();
25-
mav.setViewName("login");
26-
return mav;
32+
@Autowired
33+
public LoginController(UserRepository userRepository, OAuth2AuthorizedClientService authorizedClientService) {
34+
this.userRepository = userRepository;
35+
this.authorizedClientService = authorizedClientService;
2736
}
2837

29-
@GetMapping("secure/article-details")
38+
// @GetMapping("/login")
39+
// public ModelAndView login() {
40+
// ModelAndView mav = new ModelAndView();
41+
// mav.setViewName("login");
42+
// return mav;
43+
// }
44+
45+
@GetMapping("/secure/article-details")
3046
public ModelAndView getAllUserArticles() {
3147
ModelAndView mav = new ModelAndView();
3248
mav.addObject("users", userRepository.findAll());
3349
mav.setViewName("user/list");
3450
return mav;
3551
}
3652

53+
@ResponseBody
54+
@GetMapping("/home")
55+
public String getUserInfo(Principal user) {
56+
StringBuffer userInfo = new StringBuffer();
57+
58+
if (user instanceof UsernamePasswordAuthenticationToken) {
59+
userInfo.append(getUsernamePasswordLoginInfo(user));
60+
} else if (user instanceof OAuth2AuthenticationToken) {
61+
userInfo.append(getOAuth2LoginInfo(user));
62+
}
63+
return userInfo.toString();
64+
}
65+
66+
private StringBuffer getOAuth2LoginInfo(Principal user) {
67+
StringBuffer protectedInfo = new StringBuffer();
68+
OAuth2AuthenticationToken authToken = ((OAuth2AuthenticationToken) user);
69+
OAuth2User principal = ((OAuth2AuthenticationToken) user).getPrincipal();
70+
OAuth2AuthorizedClient authClient =
71+
this.authorizedClientService.loadAuthorizedClient(
72+
authToken.getAuthorizedClientRegistrationId(),
73+
authToken.getName());
74+
if (authToken.isAuthenticated()) {
75+
Map<String, Object> userAttributes = ((DefaultOAuth2User) authToken.getPrincipal()).getAttributes();
76+
77+
String userToken = authClient.getAccessToken().getTokenValue();
78+
protectedInfo.append("Welcome, " + userAttributes.get("login") + "<br><br>");
79+
protectedInfo.append("email: " + userAttributes.get("email") + "<br><br>");
80+
protectedInfo.append("Access Token: " + userToken + "<br><br>");
81+
protectedInfo.append(userAttributes.toString());
82+
OidcIdToken idToken = getIdToken(principal);
83+
84+
if (idToken!=null){
85+
protectedInfo.append("idToken value: "+idToken.getTokenValue()+"<br><br>");
86+
protectedInfo.append("Token mapped values <br><br>");
87+
Map<String,Object>claims = idToken.getClaims();
88+
for (String key : claims.keySet()){
89+
protectedInfo.append(" "+key+": "+claims.get(key)+"<br>");
90+
}
91+
}
92+
} else {
93+
protectedInfo.append("NA");
94+
}
95+
96+
return protectedInfo;
97+
98+
}
99+
100+
private StringBuffer getUsernamePasswordLoginInfo(Principal user) {
101+
StringBuffer usernameInfo = new StringBuffer();
102+
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
103+
if (token.isAuthenticated()) {
104+
User u = (User) token.getPrincipal();
105+
usernameInfo.append("Welcome, " + u.getUsername() + "<br>");
106+
usernameInfo.append("Role: " + u.getAuthorities());
107+
} else {
108+
usernameInfo.append("NA");
109+
}
110+
return usernameInfo;
111+
}
112+
113+
114+
private OidcIdToken getIdToken(OAuth2User principal) {
115+
if (principal instanceof DefaultOidcUser) {
116+
DefaultOidcUser oidcUser = (DefaultOidcUser) principal;
117+
return oidcUser.getIdToken();
118+
}
119+
return null;
120+
}
121+
37122
@GetMapping("/error")
38123
public String error(Model model) {
39124

40125
String errorMessage = "You are not authorized for the requested data.";
41-
log.info(" ERROR "+errorMessage);
126+
log.info(" ERROR " + errorMessage);
42127
model.addAttribute("errorMsg", errorMessage);
43128

44129
return "403";

0 commit comments

Comments
 (0)