Skip to content

Commit 0a4120d

Browse files
authored
Merge pull request #28 from CommitField/feat/#5
feat: SecurityConfig.java ์ถ”๊ฐ€ #5
2 parents ebee8f4 + 2027d41 commit 0a4120d

File tree

4 files changed

+133
-7
lines changed

4 files changed

+133
-7
lines changed
Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
package cmf.commitField.domain.user.controller;
22

3-
import org.springframework.security.core.annotation.AuthenticationPrincipal;
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.security.core.Authentication;
6+
import org.springframework.security.core.context.SecurityContextHolder;
7+
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
48
import org.springframework.security.oauth2.core.user.OAuth2User;
59
import org.springframework.web.bind.annotation.GetMapping;
610
import org.springframework.web.bind.annotation.RestController;
711

8-
import java.util.Map;
9-
1012
@RestController
1113
public class AuthController {
12-
@GetMapping("/user")
13-
public Map<String, Object> user(@AuthenticationPrincipal OAuth2User principal) {
14-
return principal.getAttributes(); // ์‚ฌ์šฉ์ž ์ •๋ณด ๋ฐ˜ํ™˜
14+
15+
@GetMapping("/login")
16+
public ResponseEntity<?> user() {
17+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
18+
19+
if (authentication instanceof OAuth2AuthenticationToken) {
20+
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
21+
return ResponseEntity.ok(principal.getAttributes()); // ์‚ฌ์šฉ์ž ์ •๋ณด ๋ฐ˜ํ™˜
22+
}
23+
24+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.");
1525
}
16-
}
26+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package cmf.commitField.global.security;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
7+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
8+
import org.springframework.security.config.http.SessionCreationPolicy;
9+
import org.springframework.security.core.context.SecurityContextHolder;
10+
import org.springframework.security.oauth2.core.user.OAuth2User;
11+
import org.springframework.security.web.SecurityFilterChain;
12+
13+
@Configuration
14+
@EnableWebSecurity
15+
public class SecurityConfig {
16+
@Bean
17+
protected SecurityFilterChain config(HttpSecurity http) throws Exception {
18+
19+
//๋กœ๊ทธ์ธ ๊ด€๋ จ ์„ค์ •
20+
http
21+
.oauth2Login(oauth2 -> oauth2
22+
.loginPage("/login") // ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ์ง€์ •
23+
.successHandler((request, response, authentication) -> {
24+
// ์ธ์ฆ ์ •๋ณด๊ฐ€ SecurityContext์— ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅ
25+
SecurityContextHolder.getContext().setAuthentication(authentication);
26+
27+
// ๋””๋ฒ„๊น…: authentication ์ •๋ณด ํ™•์ธ
28+
System.out.println("Authentication: " + authentication);
29+
System.out.println("Principal: " + authentication.getPrincipal());
30+
31+
if (authentication != null && authentication.getPrincipal() != null) {
32+
//์ธ๊ฐ€๊ฐ€ ์žˆ์œผ๋ฉด ์œ ์ € ์ •๋ณด๋ฅผ ์ €์žฅ
33+
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
34+
String username = principal.getAttribute("login");
35+
36+
// ์„ธ์…˜์— ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ถ”๊ฐ€
37+
request.getSession().setAttribute("user", username);
38+
39+
response.sendRedirect("/"); // ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
40+
} else {
41+
// ์ธ์ฆ ์‹คํŒจ ์‹œ ์ฒ˜๋ฆฌ
42+
response.sendRedirect("/login?error=authenticationFailed");
43+
}
44+
})
45+
)
46+
.sessionManagement(session -> session
47+
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // ์„ธ์…˜ ์ •์ฑ… ์„ค์ •
48+
.invalidSessionUrl("/login?error=invalidSession") // ์„ธ์…˜์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋™ํ•  URL
49+
.maximumSessions(1) // ํ•˜๋‚˜์˜ ๊ณ„์ •์œผ๋กœ ํ•œ ๋ฒˆ์— ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œ
50+
.expiredUrl("/login?error=sessionExpired") // ์„ธ์…˜ ๋งŒ๋ฃŒ ํ›„ ์ด๋™ํ•  URL ์„ค์ •
51+
);
52+
53+
//๋กœ๊ทธ์•„์›ƒ ๊ด€๋ จ ์„ค์ •
54+
http
55+
.logout(logout -> logout
56+
.logoutUrl("/logout") // ๋กœ๊ทธ์•„์›ƒ URL ์„ค์ •
57+
.logoutSuccessUrl("/") // ๋กœ๊ทธ์•„์›ƒ ์„ฑ๊ณต ํ›„ ์ด๋™ํ•  URL
58+
.invalidateHttpSession(true) // ๋กœ๊ทธ์•„์›ƒ ์‹œ ์„ธ์…˜ ๋ฌดํšจํ™”
59+
.clearAuthentication(true) // ์ธ์ฆ ์ •๋ณด ์ง€์šฐ๊ธฐ
60+
.deleteCookies("JSESSIONID") // ์„ธ์…˜ ์ฟ ํ‚ค ์‚ญ์ œ
61+
);
62+
http
63+
.csrf(
64+
AbstractHttpConfigurer::disable // CSRF ๋ณดํ˜ธ ๋น„ํ™œ์„ฑํ™”
65+
);
66+
67+
return http.build();
68+
}
69+
}
1.12 KB
Binary file not shown.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>GitHub OAuth2 ๋กœ๊ทธ์ธ ํ…Œ์ŠคํŠธ</title>
7+
</head>
8+
<body>
9+
<h1>GitHub OAuth2 ๋กœ๊ทธ์ธ ํ…Œ์ŠคํŠธ</h1>
10+
11+
<!-- ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ -->
12+
<a href="/oauth2/authorization/github" id="loginBtn" style="display: none;">
13+
<button>GitHub ๋กœ๊ทธ์ธ</button>
14+
</a>
15+
16+
<!-- ๋กœ๊ทธ์•„์›ƒ ๋ฒ„ํŠผ -->
17+
<button id="logoutBtn" style="display: none;">๋กœ๊ทธ์•„์›ƒ</button>
18+
19+
<h2>์‚ฌ์šฉ์ž ์ •๋ณด</h2>
20+
<pre id="userInfo">๋กœ๊ทธ์ธ ํ›„ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค...</pre>
21+
22+
<script>
23+
async function fetchUser() {
24+
try {
25+
const response = await fetch('/login');
26+
if (!response.ok) throw new Error("Not logged in");
27+
28+
const data = await response.json();
29+
document.getElementById("userInfo").textContent = JSON.stringify(data, null, 2);
30+
document.getElementById("logoutBtn").style.display = "block";
31+
document.getElementById("loginBtn").style.display = "none";
32+
} catch (error) {
33+
document.getElementById("userInfo").textContent = "๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.";
34+
document.getElementById("logoutBtn").style.display = "none";
35+
document.getElementById("loginBtn").style.display = "inline-block";
36+
}
37+
}
38+
39+
document.getElementById("logoutBtn").addEventListener("click", async () => {
40+
await fetch('/logout', { method: 'POST' }); // POST ๋ฐฉ์‹์œผ๋กœ ๋กœ๊ทธ์•„์›ƒ
41+
fetchUser(); // ๋กœ๊ทธ์•„์›ƒ ํ›„ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐฑ์‹ 
42+
});
43+
44+
fetchUser(); // ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
45+
</script>
46+
</body>
47+
</html>

0 commit comments

Comments
ย (0)