-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspringsecurity.html
More file actions
813 lines (641 loc) · 40 KB
/
springsecurity.html
File metadata and controls
813 lines (641 loc) · 40 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
<!DOCTYPE html>
<html>
<head>
<!-- Document Settings -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Base Meta -->
<!-- dynamically fixing the title for tag/author pages -->
<title>Spring Security 연습</title>
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Styles'n'Scripts -->
<link rel="stylesheet" type="text/css" href="/assets/built/screen.css" />
<link rel="stylesheet" type="text/css" href="/assets/built/screen.edited.css" />
<link rel="stylesheet" type="text/css" href="/assets/built/syntax.css" />
<!-- custom.css -->
<link rel="stylesheet" type="text/css" href="/assets/built/custom.css"/>
<!-- font awesome -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- 웹폰트 추가 -->
<link rel="stylesheet" href="https://fonts.googleapis.com/earlyaccess/nanumgothic.css">
<!-- syntax.css 추가 -->
<link rel="stylesheet" type="text/css" href="/assets/built/syntax.css"/>
<!-- highlight.js -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
<style>.hljs { background: none; }</style>
<!--[if IE]>
<style>
p, ol, ul{
width: 100%;
}
blockquote{
width: 100%;
}
</style>
<![endif]-->
<!-- This tag outputs SEO meta+structured data and other important settings -->
<meta name="description" content="온리 공부를 위한 블로그" />
<link rel="shortcut icon" href="https://sanseongKo.github.io/assets/built/images/favicon.jpg" type="image/png" />
<link rel="canonical" href="https://sanseongKo.github.io/springsecurity" />
<meta name="referrer" content="no-referrer-when-downgrade" />
<!--title below is coming from _includes/dynamic_title-->
<meta property="og:site_name" content="SanseongKo's Blog" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Spring Security 연습" />
<meta property="og:description" content="기술 면접중 스프링 시큐리티에 관하여 질문을 받았고, 대답을 못했다. 돌아가는 모습은 내가 아는 모습은 비슷하지만, 지원을 해주는 것에서 많이 차이가 나는 것 같다. 편한기능이 많고, 알아두면 좋을 것 같다. 물론 어떻게 돌아가는지도 넣을 것이고, 자료는 유튜브 데어 프로그래밍님의 유튜브에서 가져왔고 설명이 잘되어 있는 것 같으니, 궁금할 땐 클릭해서 들어가 보자.(유튜브로" />
<meta property="og:url" content="https://sanseongKo.github.io/springsecurity" />
<meta property="og:image" content="https://sanseongKo.github.io/assets/built/images/spring/spring.png" />
<meta property="article:publisher" content="https://www.facebook.com/" />
<meta property="article:author" content="https://www.facebook.com/" />
<meta property="article:published_time" content="2021-06-18T00:00:00+09:00" />
<meta property="article:modified_time" content="2021-06-18T00:00:00+09:00" />
<meta property="article:tag" content="Spring" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Spring Security 연습" />
<meta name="twitter:description" content="기술 면접중 스프링 시큐리티에 관하여 질문을 받았고, 대답을 못했다. 돌아가는 모습은 내가 아는 모습은 비슷하지만, 지원을 해주는 것에서 많이 차이가 나는 것 같다. 편한기능이 많고, 알아두면 좋을 것 같다. 물론 어떻게 돌아가는지도 넣을 것이고, 자료는 유튜브 데어 프로그래밍님의 유튜브에서 가져왔고 설명이 잘되어 있는 것 같으니, 궁금할 땐 클릭해서 들어가 보자.(유튜브로" />
<meta name="twitter:url" content="https://sanseongKo.github.io/" />
<meta name="twitter:image" content="https://sanseongKo.github.io/assets/built/images/spring/spring.png" />
<meta name="twitter:label1" content="Written by" />
<meta name="twitter:data1" content="SanseongKo's Blog" />
<meta name="twitter:label2" content="Filed under" />
<meta name="twitter:data2" content="Spring" />
<meta name="twitter:site" content="@" />
<meta name="twitter:creator" content="@" />
<meta property="og:image:width" content="1400" />
<meta property="og:image:height" content="933" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Website",
"publisher": {
"@type": "Organization",
"name": "SanseongKo's Blog",
"logo": "https://sanseongKo.github.io/"
},
"url": "https://sanseongKo.github.io/springsecurity",
"image": {
"@type": "ImageObject",
"url": "https://sanseongKo.github.io/assets/built/images/spring/spring.png",
"width": 2000,
"height": 666
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://sanseongKo.github.io/springsecurity"
},
"description": "기술 면접중 스프링 시큐리티에 관하여 질문을 받았고, 대답을 못했다. 돌아가는 모습은 내가 아는 모습은 비슷하지만, 지원을 해주는 것에서 많이 차이가 나는 것 같다. 편한기능이 많고, 알아두면 좋을 것 같다. 물론 어떻게 돌아가는지도 넣을 것이고, 자료는 유튜브 데어 프로그래밍님의 유튜브에서 가져왔고 설명이 잘되어 있는 것 같으니, 궁금할 땐 클릭해서 들어가 보자.(유튜브로"
}
</script>
<!-- <script type="text/javascript" src="https://demo.ghost.io/public/ghost-sdk.min.js?v=724281a32e"></script>
<script type="text/javascript">
ghost.init({
clientId: "ghost-frontend",
clientSecret: "f84a07a72b17"
});
</script> -->
<meta name="generator" content="Jekyll 3.6.2" />
<link rel="alternate" type="application/rss+xml" title="Spring Security 연습" href="/feed.xml" />
</head>
<body class="post-template">
<div class="site-wrapper">
<!-- All the main content gets inserted here, index.hbs, post.hbs, etc -->
<!-- default -->
<!-- The tag above means: insert everything in this file
into the {body} of the default.hbs template -->
<header class="site-header outer">
<div class="inner">
<nav class="site-nav">
<div class="site-nav-left">
<a class="site-nav-logo" href="https://sanseongKo.github.io/">SanseongKo's Blog</a>
<ul class="nav" role="menu">
<li class="nav-home" role="menuitem"><a href="/">Home</a></li>
<li class="nav-about" role="menuitem"><a href="/about/">About</a></li>
<li class="nav-jekyll" role="menuitem"><a href="/tag/algorithm/">Algorithm</a></li>
<li class="nav-python" role="menuitem"><a href="/tag/java/">Java</a></li>
<li class="nav-python" role="menuitem"><a href="/tag/interview/">기술 면접</a></li>
<li class="nav-python" role="menuitem"><a href="/tag/codingtest/">코테 연습</a></li>
<li class="nav-python" role="menuitem"><a href="/tag/spring/">스프링</a></li>
<li class="nav-archive" role="menuitem">
<a href="/archive.html">All Posts</a>
</li>
<li class="nav-archive" role="menuitem">
<a href="/author_archive.html">Tag별 Posts</a>
</li>
</ul>
</div>
<div class="site-nav-right">
<div class="social-links">
</div>
<a class="subscribe-button" href="#subscribe">Search</a>
</div>
</nav>
</div>
</header>
<!-- Everything inside the #post tags pulls data from the post -->
<!-- #post -->
<main id="site-main" class="site-main outer" role="main">
<div class="inner">
<article class="post-full tag-spring post tag-java ">
<header class="post-full-header">
<section class="post-full-meta">
<time class="post-full-meta-date" datetime="18 June 2021">18 June 2021</time>
<span class="date-divider">/</span>
<a href='/tag/spring/'>SPRING</a>
</section>
<h1 class="post-full-title">Spring Security 연습</h1>
</header>
<figure class="post-full-image" style="background-image: url(/assets/built/images/spring/spring.png)">
</figure>
<!--커버필요없으면 주석 -->
<section class="post-full-content">
<div class="kg-card-markdown">
<p>기술 면접중 스프링 시큐리티에 관하여 질문을 받았고, 대답을 못했다. 돌아가는 모습은 내가 아는 모습은 비슷하지만, 지원을 해주는 것에서 많이 차이가
나는 것 같다. 편한기능이 많고, 알아두면 좋을 것 같다. 물론 어떻게 돌아가는지도 넣을 것이고, 자료는 유튜브 <a href="https://www.youtube.com/watch?v=riwrVN1JVbU">데어 프로그래밍</a>님의
유튜브에서 가져왔고 설명이 잘되어 있는 것 같으니, 궁금할 땐 클릭해서 들어가 보자.(유튜브로 강의를 정말 잘해 놓으셨다.)</p>
<h3>Spring Security 연습 1(2021-06-17)</h3>
<p><br />
처음 시작에서 Spring Security 의존주입을 하고 나서, yml파일을 생성하고 내용을 정리해준다. 브라우저에 접속하여 url을 적으면, 자동으로 스프링
시큐리티가 login페이지로 넘겨준다. 아이디는 기본 user이며, 비밀번호는 처음 서버를 실행하고 나서 콘솔에 사진처럼 나타나게된다. spring security
의존주입시 처음 들어가는 모든 요청 페이지는 막혀서 로그인을 해줘야하고 로그인이 되어야 접근이 가능하다는 점 유의하자. 또한 로그아웃도 지원하기 때문에,
다시 서버를 실행하였다면, 로그아웃 한번 해주고 실행하자.(비밀번호도 재실행 될 때마다 변경됨)
<img src="./assets/built/images/spring/securitypassword.PNG" alt="ex_screenshot" />
<b>MustacheViewResolver</b>
해당 유튜브 강의에서는 html을 이용하여 초반에 뷰를 작성하였다. 하지만 처음 의존 주입을 Mustache로 하였기 때문에, 해당 configuration 클래스를
생성하고, MustacheViewResolver자료형으로 참조변수를 만들어 사용할 수 있다.</p>
<pre><code class="language-angular2html">MustacheViewResolver resolver = new MustacheViewResolver();
resolver.setCharset("UTF-8");
resolver.setContentType("text/html; charset=UTF-8");
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
</code></pre>
<p>이런식으로 만들어졌을 경우 .mustache로 설정되어 있던 suffix가 html로 경로 설정이 될 수 있도록 해준다.</p>
<h3>Spring Security 연습 2(2021-06-18)</h3>
<p><b>@EnableWebSecurity</b>
웹 보안을 활성화하고, WebSecurityConfigurer을 상속받아 클래스를 설정할 때 자주 쓰인다. @Configuration 클래스에 @EnableWebSecurity을 추가하여
스프링 시큐리티를 설정할 클래스라고 정의한다.
<br />
<br />
<b>WebSecurityConfigurer</b>는 WebSecurityConfigurer 인스턴스를 편리하게 만들기 위하여 사용한다. 상속을 받게 되면, configure 메소드를 오버
라이딩 할 수 있고, 파라미터는 HttpSecurity 객체를 받게 된다.
<br />
<br />
<b>authorizeRequests()</b>메서드는 시큐리티 처리에 HttpServletRequest를 이용한다는 것을 의미하고,
<br />
<br />
<b>antMatchers()</b>는 특정 경로를 지정해줄 수 있는 메소드이다.
<br />
<br /></p>
<h4>특정 경로 지정 후 사용 할 수 있는 인증 메서드</h4>
<p>anonymous(): 인증되지 않은 사용자가 접근할 수 있습니다.
authenticated(): 인증된 사용자만 접근할 수 있습니다.
fullyAuthenticated(): 완전히 인증된 사용자만 접근할 수 있습니다(?)
hasRole() or hasAnyRole(): 특정 권한을 가지는 사용자만 접근할 수 있습니다.
hasAuthority() or hasAnyAuthority():특정 권한을 가지는 사용자만 접근할 수 있습니다.
hasIpAddress(): 특정 아이피 주소를 가지는 사용자만 접근할 수 있습니다.
access(): SpEL 표현식에 의한 결과에 따라 접근할 수 있습니다.
not(): 접근 제한 기능을 해제합니다.
permitAll() or denyAll(): 접근을 전부 허용하거나 제한합니다.
rememberMe(): 리멤버 기능을 통해 로그인한 사용자만 접근할 수 있습니다.
csrf().disable(): csrf(사용자의 의지와는 무관한 수정/삭제/등록 등의 행위를 요청하는 것을 의미한다.)를 하지 못하게 합니다.
<br />
<br />
<br /></p>
<p>출처: <a href="https://postitforhooney.tistory.com/entry/SpringSecurity-초보자가-이해하는-Spring-Security-퍼옴">PostIT</a>
<br />
<br />
<br />
<br /></p>
<p>또한 이후에,</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">.</span><span class="nx">formLogin</span><span class="p">()</span>
<span class="p">.</span><span class="nx">loginPage</span><span class="p">(</span><span class="dl">"</span><span class="s2">/loginForm</span><span class="dl">"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">loginProcessingUrl</span><span class="p">(</span><span class="dl">"</span><span class="s2">/login</span><span class="dl">"</span><span class="p">)</span>
<span class="p">.</span><span class="nx">defaultSuccessUrl</span><span class="p">(</span><span class="dl">"</span><span class="s2">/</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>
<p>이렇게 작성을 하게된다면, loginPage는 로그인 페이지가 어디인지, loginProcessingUrl은 login주소가 호출될 떄 시큐리티가 낚아채서 대신 로그인을 진행해주는 메소드이며,
.defaultSuccessUrl은 로그인 이후에 보여질 기본 페이지이며, 특정페이지로 접속하려 할 때 인증이 필요하여 로그인 페이지로 넘어갈 경우 그 로그인페이지에서 전에 config에서 설정해 놓은 기본 경로로
가지 않고 특정페이지가 보여지게 된다.
<br /></p>
<p><b>OAuth(2021-06-23추가)</b><br /><br />
OAuth2는 인증을 위한 표준 프로토콜이다.(정의)
해당 인증으로 타 사이트의 API를 이용할 수 있게 되는 것이다.
스프링 시큐리티 라이브러리중 OAuth라는 라이브러리가 있었다. 예전 프로젝트를 할 때 네이버나 카카오 로그인 API를 사용할 때 개인 키를 적어두고 이를 사용해서
토큰과 정보를 받아왔었다. 하지만, OAuth Client 라이브러리를 사용하니 그럴 필요없이 정해진 경로로 매핑을 해놓고, 키와 비밀번호를 property.yml에 저장해
놓으니, 굳이 토큰을 받아올 uri을 적고 가져오는 코드를 작성할 필요없이 로그인에 필요한 정보를 가져올 수 있었다.
예를 들어 구글 로그인 API를 사용할 경우 http://localhost:8080/login/oauth2/code/google 적었다고 하면, login/oauth2/code/은 고정이고 이후
google이나 facebook등은 해당 사이트에 맞게 적어주면 되었다.</p>
<p><a href="https://developers.payco.com/guide/development/start">페이코 개발자 센터</a> 해당 링크에서 OAuth의 인증과정과 프로세스를 확인 할 수 있다.
<br /><br />
OAuth서비스 코드를 작성할 때 DefaultOAuth2UserService를 상속받아 사용하면 되며, loadUser 메소드를 오버라이드하여 안에 내용을 채워주면 된다.
<br /><br />
해당 유튜브 영상을 보며, 모르겠는 메소드를 찾아보았다.
<br /><br />
<b>userInfoEndpoint</b>
OAuth2 로그인 성공 이후 사용자 정보를 가져올 때의 설정을 담당
<br /><br />
<b>userService</b>
소셜 로그인 완료 후 후조치를 진행할 UserService 인터페이스의 구현체를 등록해줘야함
<br /><br />
후속 조치로는 데이터를 받아오면 바로 가입시켜주든 회원 가입 페이지로 이동을 시키든 할 수 있고, 아무래도 예전 프로젝트에서 사용하는 코드들 보다 많이
유용하고 편리하였다. 하지만 그래도 부트를 사용하기전 스프링에서 로그인 API사용하기 위한 코드를 직접 만들었던 적이 있어서 그런지 돌아가는 구조를 이해하는데
쉬웠다.</p>
<p><br /><br /></p>
<h3>JWT를 들어가기 전에(2021=06-24)</h3>
<p>JWT를 들어가기 전에 알아둬야 할 것이 있다고 유튜브 강의에서 나와서 정리를 해보려 한다.</p>
<p><br /><br />
<b>Session과 Cookie</b>
<br /><br />
우선 세션과 쿠키에 관하여 알아야 하는데, 이 부분은 전에 공부한 적이 있어서 어느정도 이해가 되어있는 상태로 보았다.<br />
쉽게 설명하자면, 세션은 서버가 기억하는 것이고, 쿠키는 사용자의 브라우저에서 기억하는 것이라고 생각할 수 있다.<br />
우선 처음 사용자가 요청을 보내면 서버는 해당 사용자의 세션객체를 만들어 사용자에게 Header에 쿠키를 만들어 보내준다.<br />
그럼 다음 사용자는 이후에 요청을 한다면 쿠키의 세션 아이디를 서버로 보내고 서버는 이 사용자가 전에 요청을 보낸적이 있는지 체크하게 된다.<br />
<br /><br />
그런데, 서버에서 처리할 수 있는 요청이 50개인데 만약 70개의 요청이 들어온다면? 그럼 앞의 요청이 끝날 때까지 사용자는 기다려야 할 것이다. 이럴 경우,
서버를 여러개 두어 요청이 초과할 경우 다른 서버로 이 요청을 보내주면 되는데, 이것을 로드 밸런싱이라고 한다.
<br />
하지만 로드밸런싱을 할 경우 문제가 되는 부분이 있다. 바로 사용자는 처음 서버1에게 요청을 보내어 쿠키에 세션아이디를 가지고 있다고 가정하면, 로드 밸런싱으로
인하여 서버2에 요청이 갔을 경우 서버 2는 이 사용자를 처음 요청한 사용자로 볼 수 있다는 것이다.
<br /><br />
이런 문제를 해결하기 위하여 강의에서는 4가지를 말하였는데</p>
<ol>
<li>처음 요청을 로드 밸런싱으로 처리할 경우 다음 요청은 처음 요청한 곳으로 가게한다.</li>
<li>각 서버가 세션을 공유하는 방법</li>
<li>세션을 데이터 베이스에 저장하는 방법</li>
<li>세션을 램서버에 저장하고 램서버를 각 서버가 공유하는 방법
<br /><br />
유튜브에서는 4번 방법이 제일 빠르다고 표현하였다. 자세한 부분은 접해볼 기회가 있다면 확인하고, 우선 이런거 까지만 있다정도로 확인하고 넘어가려 한다.
또한 jwt는 이 세션의 문제점을 보완하려고 나온 것이라고 한다.
<br /><br />
<b>CIA</b>
CIA란,</li>
<li>C: 기밀성(Confidentiality)의 약자로 주고 받는 데이터가 비밀스러워야 한다는 것이다.</li>
<li>I: 무결성(Integrity)의 약자로, 데이터는 변하면 안된다.</li>
<li>A: 가용성(Availability)의 약자로, 가용성은 항상 특정한 방식에 의해 사용 가능하여야 한다.</li>
</ol>
<p>하지만, 이 부분에서 만약 A가 B에게 “안녕”이라는 데이터를 전달하려고 한다. 하지만 A와 B사이에 나쁜 C가 있어서, 만약 A가 보냈을 때, C가 그 내용을
탈취하여 내용을 변경하거나, 탈취하고 소멸시켜 버릴 경우 B는 데이터를 받지 못하고, 데이터를 받았다고 하더라도 그 내용이 변경되어 잘 못 전달될 가능성이 있다.
그렇기 때문에 A는 데이터를 어떠한 박스에 넣고 그걸 자물쇠로 잠궈서 해당 열쇠로만 열리게 만들었다고 하면 C는 그걸 탈취하더라도 내용을 볼 수가 없다.
하지만, 문제가 생긴다. 잘 보내졌다고 하더라도 B는 열쇠가 없어 확인을 하지 못할 것이다. 그렇다고 A가 열쇠를 같이 보낸다면? C가 탈취하면 위와 같은 상황이
반복된다. 이렇다면 기밀성, 무결성, 가용성이 모두 침해당하게 된다.
<br /><br />
<b>RSA</b>
<br /><br />
이렇기 때문에, 나온 방법이 RSA 암호화 방식이다. 이 방식은 공개키와 개인키로 이루어져 있고, 이런 방식을 symmetric-key algorithm 즉 대칭키 알고리즘이라고 한다.
위의 예시대로 A가 B에게 데이터를 전달하려고 할때, B가 공개해놓은 키로 암호화를 하여 A가 B에게 전송하면 C가 탈취하더라도 내용을 볼 수가 없다. 왜? 데이터는
B의 개인키로만 열 수 있기 때문에, 하지만 이럴 경우 C가 탈취해서 그냥 데이터를 소멸시켜버리고 새로운 데이터를 만들어 B에게 전송할 수도 있다. 이럴 경우,
B는 A가 만들줄 알고 데이터를 받을 것이고 내용을 확인 할 것이다.
<br />
그렇기 때문에, B의 공개키로 암호화된 데이터를 한번더 A의 개인키로 감싸는 것이다. 그렇다면, C가 탈취했다고 하더라도 A가 보낸 것을 알아도, 다시 A가 보낸 것처럼
만들 수 없다. 왜? A의 개인키를 모르기 때문에, 그렇다면, B는 데이터를 받았을 때 어떻게 확인하여야 할까. A가 미리 공개해둔 공개키로 열어 본다. 그렇다면, A가
보낸 것을 확인, 더불어 자신의 개인키로 내용을 확인할 수 있게 된다.
<br /><br />
이렇게, CIA의 문제를 RSA로 해결하고 위의 사전지식을 가지고 JWT를 사용해보겠다.
전에 기사공부를 하다가 기밀성 무결성 가용성 RSA 등의 암호화 방식을 공부했지만, 예를 들어 설명하니 조금 새롭게 다가왔고 정립이 된 것 같다. 좋군
<br /><br />
<b>스프링 시큐리티 정리</b>
<br /></p>
<ol>
<li>PrincipalDetails
<ul>
<li>생성자</li>
<li>UserDetails, OAuth2User를 상속받음
나머지 전부 오버라이딩
<br /></li>
</ul>
</li>
</ol>
<ul>
<li>@override getAuthorities()를 오버라이딩하는데
collection객체 생성 add를 GrantedAuthority객체를 생성하여 함수를 적용하는데,
넣으면 자동으로 안에 오버라이딩이 됨
계정이 가지고 있는 권한 목록을 가져옴
<br /><br />
public boolean isAccountNonExpired() {//계정이 만료되지 않았는지 리턴(true: 만료되지 않음)
<br />
public boolean isAccountNonLocked() {//계정이 잠겨있지 않은지를 리턴(true를 리턴하면 계정이 잠겨있지 않음)
<br />
public boolean isCredentialsNonExpired() {//계정의 패스워드가 만료되지 않았는지 리턴(true를 리턴하면 만료되지 않음)
<br />
public boolean isEnabled() {//계정이 사용가능한 계정인지 리턴
<br /></li>
</ul>
<ol>
<li>PrincipalDetailsService
userRepository 객체에서 findByUsername으로 이름을 가져와 User객체의 userEntity에 넣음 (PrincipalDetails)에 user를 넣어 불러옴(일반 로그인)</li>
</ol>
<p><br /></p>
<ol>
<li>SecurityConfig
스프링 시큐리티에 관한 설정들이 모여있는 곳
<br />
@Configuration: 해당 클래스에서 1개 이상의 Bean을 생성하고 있음을 명시
<br />
@EnableWebSecurity: 웹 보안을 활성화하고, WebSecurityConfigurer을 상속받아 클래스를 설정할 때 자주 쓰인다. @Configuration 클래스에 @EnableWebSecurity을 추가하여
스프링 시큐리티를 설정할 클래스라고 정의한다.
<br />
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true): 시큐어 어노테이션 활성화, preAuthorize 어노테이션 활성화
securedEnabled = true 로 설정하면 @Secured 어노테이션 사용 가능
<br />
anonymous(): 인증되지 않은 사용자가 접근할 수 있습니다.
<br />
authenticated(): 인증된 사용자만 접근할 수 있습니다.
<br />
fullyAuthenticated(): 완전히 인증된 사용자만 접근할 수 있습니다(?)
<br />
hasRole() or hasAnyRole(): 특정 권한을 가지는 사용자만 접근할 수 있습니다.
<br />
hasAuthority() or hasAnyAuthority():특정 권한을 가지는 사용자만 접근할 수 있습니다.
<br />
hasIpAddress(): 특정 아이피 주소를 가지는 사용자만 접근할 수 있습니다.
<br />
access(): SpEL 표현식에 의한 결과에 따라 접근할 수 있습니다.
<br />
not(): 접근 제한 기능을 해제합니다.
<br />
permitAll() or denyAll(): 접근을 전부 허용하거나 제한합니다.
<br />
rememberMe(): 리멤버 기능을 통해 로그인한 사용자만 접근할 수 있습니다.
<br />
csrf().disable(): csrf(사용자의 의지와는 무관한 수정/삭제/등록 등의 행위를 요청하는 것을 의미한다.)를 하지 못하게 합니다.
<br />
antMatchers(): 특정 경로를 지정해줄 수 있는 메소드이다.
<br />
authorizeRequests(): 메서드는 시큐리티 처리에 HttpServletRequest를 이용한다는 것을 의미하고,
<br />
WebSecurityConfigurer: WebSecurityConfigurer 인스턴스를 편리하게 만들기 위하여 사용한다. 상속을 받게 되면, configure 메소드를 오버
라이딩 할 수 있고, 파라미터는 HttpSecurity 객체를 받게 된다.
<br /></li>
<li>PrincipalOauth2UserService
<br />
DefaultOAuth2UserService를 상속 받음
<br />
loadUser를 오버라이드함
<br /></li>
</ol>
</div>
</section>
<!-- Email subscribe form at the bottom of the page -->
<!--
<section class="subscribe-form">
<h3 class="subscribe-form-title">Subscribe to SanseongKo's Blog</h3>
<p>Get the latest posts delivered right to your inbox</p>
<span id="searchform" method="post" action="/subscribe/" class="">
<input class="confirm" type="hidden" name="confirm" />
<input class="location" type="hidden" name="location" />
<input class="referrer" type="hidden" name="referrer" />
<div class="form-group">
<input class="subscribe-email" onkeyup="myFunc()"
id="searchtext" type="text" name="searchtext"
placeholder="Search..." />
</div>
<script type="text/javascript">
function myFunc() {
if(event.keyCode == 13) {
var url = encodeURIComponent($("#searchtext").val());
location.href = "/search.html?query=" + url;
}
}
</script>
</span>
</section>
-->
<footer class="post-full-footer">
<!-- Everything inside the #author tags pulls data from the author -->
<!-- #author-->
<!-- /author -->
</footer>
<!-- If you use Disqus comments, just uncomment this block.
The only thing you need to change is "test-apkdzgmqhj" - which
should be replaced with your own Disqus site-id. -->
<section class="post-full-comments">
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
var this_page_url = 'https://sanseongKo.github.io/springsecurity';
var this_page_identifier = '/springsecurity';
var this_page_title = 'Spring Security 연습';
};
(function() {
var d = document, s = d.createElement('script');
s.src = 'https://xxxxxxxx.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
</section>
</article>
</div>
</main>
<!-- Links to Previous/Next posts -->
<aside class="read-next outer">
<div class="inner">
<div class="read-next-feed">
<!-- If there's a next post, display it using the same markup included from - partials/post-card.hbs -->
<article class="post-card post-template">
<a class="post-card-image-link" href="/codingtest-codingclass">
<div class="post-card-image" style="background-image: url(/assets/built/images/codingtest/inflearn.png)"></div>
</a>
<div class="post-card-content">
<a class="post-card-content-link" href="/codingtest-codingclass">
<header class="post-card-header">
<span class="post-card-tags">Codingtest</span>
<h2 class="post-card-title">inflearn강의 복습</h2>
</header>
<section class="post-card-excerpt">
<p>뭔가 계속 불안해서 결국 인프런의 강의를 질렀다. 강의에서 나오는 내용들 위주로 공부를 진행하려고 한다.
</p>
</section>
</a>
<footer class="post-card-meta">
<span class="reading-time">
1 min read
</span>
</footer>
</div>
</article>
<!-- If there's a previous post, display it using the same markup included from - partials/post-card.hbs -->
<article class="post-card post-template">
<a class="post-card-image-link" href="/codingtest-2021_kakao01">
<div class="post-card-image" style="background-image: url(/assets/built/images/codingtest/2021review.png)"></div>
</a>
<div class="post-card-content">
<a class="post-card-content-link" href="/codingtest-2021_kakao01">
<header class="post-card-header">
<span class="post-card-tags">Codingtest</span>
<h2 class="post-card-title">카카오 2021 블라인드 코딩테스트 1번</h2>
</header>
<section class="post-card-excerpt">
<p>문제 카카오에 입사한 신입 개발자 네오는 “카카오계정개발팀”에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. “네오”에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된</p>
</section>
</a>
<footer class="post-card-meta">
<span class="reading-time">
1 min read
</span>
</footer>
</div>
</article>
</div>
</div>
</aside>
<!-- Floating header which appears on-scroll, included from includes/floating-header.hbs -->
<div class="floating-header">
<div class="floating-header-logo">
<a href="https://sanseongKo.github.io/">
<span>SanseongKo's Blog</span>
</a>
</div>
<span class="floating-header-divider">—</span>
<div class="floating-header-title">Spring Security 연습</div>
<div class="floating-header-share">
<div class="floating-header-share-label">Share this <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M7.5 15.5V4a1.5 1.5 0 1 1 3 0v4.5h2a1 1 0 0 1 1 1h2a1 1 0 0 1 1 1H18a1.5 1.5 0 0 1 1.5 1.5v3.099c0 .929-.13 1.854-.385 2.748L17.5 23.5h-9c-1.5-2-5.417-8.673-5.417-8.673a1.2 1.2 0 0 1 1.76-1.605L7.5 15.5zm6-6v2m-3-3.5v3.5m6-1v2"/>
</svg>
</div>
<a class="floating-header-share-tw" href="https://twitter.com/share?text=Spring+Security+%EC%97%B0%EC%8A%B5&url=https://sanseongKo.github.io/springsecurity"
onclick="window.open(this.href, 'share-twitter', 'width=550,height=235');return false;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>
</a>
<a class="floating-header-share-fb" href="https://www.facebook.com/sharer/sharer.php?u=https://sanseongKo.github.io/springsecurity"
onclick="window.open(this.href, 'share-facebook','width=580,height=296');return false;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"/></svg>
</a>
</div>
<progress class="progress" value="0">
<div class="progress-container">
<span class="progress-bar"></span>
</div>
</progress>
</div>
<!-- /post -->
<!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs -->
<!-- Previous/next page links - displayed on every page -->
<!-- The footer at the very bottom of the screen -->
<footer class="site-footer outer">
<div class="site-footer-content inner">
<section class="copyright"><a href="https://sanseongKo.github.io/">SanseongKo's Blog</a> © 2021</section>
<section class="poweredby">Proudly published with <a href="https://jekyllrb.com/">Jekyll</a> &
<a href="https://pages.github.com/" target="_blank" rel="noopener">GitHub Pages</a> using
<a href="https://github.com/jekyller/jasper2" target="_blank" rel="noopener">Jasper2</a></section>
<nav class="site-footer-nav">
<a href="/">Latest Posts</a>
<a href="https://ghost.org" target="_blank" rel="noopener">Ghost</a>
</nav>
</div>
</footer>
</div>
<!-- The big email subscribe modal content -->
<div id="subscribe" class="subscribe-overlay">
<a class="subscribe-overlay-close" href="#"></a>
<div class="subscribe-overlay-content">
<h1 class="subscribe-overlay-title">Search SanseongKo's Blog</h1>
<p class="subscribe-overlay-description">
lunr.js를 이용한 posts 검색 </p>
<span id="searchform" method="post" action="/subscribe/" class="">
<input class="confirm" type="hidden" name="confirm" />
<input class="location" type="hidden" name="location" />
<input class="referrer" type="hidden" name="referrer" />
<div class="form-group">
<input class="subscribe-email" onkeyup="myFunc()"
id="searchtext" type="text" name="searchtext"
placeholder="Search..." />
</div>
<script type="text/javascript">
function myFunc() {
if(event.keyCode == 13) {
var url = encodeURIComponent($("#searchtext").val());
location.href = "/search.html?query=" + url;
}
}
</script>
</span>
</div>
</div>
<!-- highlight.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.10.0/components/prism-abap.min.js"></script>
<script>$(document).ready(function() {
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
});</script>
<!-- jQuery + Fitvids, which makes all video embeds responsive -->
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous">
</script>
<script type="text/javascript" src="/assets/js/jquery.fitvids.js"></script>
<script type="text/javascript" src="https://demo.ghost.io/assets/js/jquery.fitvids.js?v=724281a32e"></script>
<!-- Paginator increased to "infinit" in _config.yml -->
<!-- if paginator.posts -->
<!-- <script>
var maxPages = parseInt('');
</script>
<script src="/assets/js/infinitescroll.js"></script> -->
<!-- /endif -->
<!-- Add Google Analytics -->
<!-- Google Analytics Tracking code -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-xxxxxxxx-x', 'auto');
ga('send', 'pageview');
</script>
<!-- The #block helper will pull in data from the #contentFor other template files. In this case, there's some JavaScript which we only want to use in post.hbs, but it needs to be included down here, after jQuery has already loaded. -->
<script>
// NOTE: Scroll performance is poor in Safari
// - this appears to be due to the events firing much more slowly in Safari.
// Dropping the scroll event and using only a raf loop results in smoother
// scrolling but continuous processing even when not scrolling
$(document).ready(function () {
// Start fitVids
var $postContent = $(".post-full-content");
$postContent.fitVids();
// End fitVids
var progressBar = document.querySelector('progress');
var header = document.querySelector('.floating-header');
var title = document.querySelector('.post-full-title');
var lastScrollY = window.scrollY;
var lastWindowHeight = window.innerHeight;
var lastDocumentHeight = $(document).height();
var ticking = false;
function onScroll() {
lastScrollY = window.scrollY;
requestTick();
}
function onResize() {
lastWindowHeight = window.innerHeight;
lastDocumentHeight = $(document).height();
requestTick();
}
function requestTick() {
if (!ticking) {
requestAnimationFrame(update);
}
ticking = true;
}
function update() {
var trigger = title.getBoundingClientRect().top + window.scrollY;
var triggerOffset = title.offsetHeight + 35;
var progressMax = lastDocumentHeight - lastWindowHeight;
// show/hide floating header
if (lastScrollY >= trigger + triggerOffset) {
header.classList.add('floating-active');
} else {
header.classList.remove('floating-active');
}
progressBar.setAttribute('max', progressMax);
progressBar.setAttribute('value', lastScrollY);
ticking = false;
}
window.addEventListener('scroll', onScroll, {passive: true});
window.addEventListener('resize', onResize, false);
update();
});
</script>
<!-- Ghost outputs important scripts and data with this tag - it should always be the very last thing before the closing body tag -->
<!-- ghost_foot -->
</body>
</html>