質問編集履歴

2

UserDetailsServiceインターフェースの実装クラス、セキュリティコンフィグレーションクラスを追記しました。

2020/02/07 13:46

投稿

shinichi-ito
shinichi-ito

スコア9

test CHANGED
File without changes
test CHANGED
@@ -34,9 +34,11 @@
34
34
 
35
35
  Entity
36
36
 
37
+
38
+
39
+
40
+
37
- ```ここに言語を入力
41
+ ```ここに言語を入力
38
-
39
-
40
42
 
41
43
  @Entity
42
44
 
@@ -74,6 +76,8 @@
74
76
 
75
77
  }
76
78
 
79
+ ```
80
+
77
81
  UserDetailsインターフェースの実装コード
78
82
 
79
83
  このコード内で「LoginUser」からidを取得する独自メソッドを設定しています。
@@ -82,6 +86,8 @@
82
86
 
83
87
 
84
88
 
89
+
90
+
85
91
  ```ここに言語を入力
86
92
 
87
93
  public class UserDetailsImpl implements UserDetails {
@@ -208,6 +214,8 @@
208
214
 
209
215
  ```
210
216
 
217
+
218
+
211
219
 
212
220
 
213
221
  controllerクラス内のメソッドに引数として「@AuthenticationPrincipal UserDetailsImpl userDetails」を設定しています。

1

UserDetailsServiceインターフェースの実装クラス、セキュリティコンフィグレーションクラスを追記しました。

2020/02/07 13:46

投稿

shinichi-ito
shinichi-ito

スコア9

test CHANGED
File without changes
test CHANGED
@@ -36,33 +36,7 @@
36
36
 
37
37
  ```ここに言語を入力
38
38
 
39
- package com.example.demo.entity;
39
+
40
-
41
-
42
-
43
- import javax.persistence.Column;
44
-
45
- import javax.persistence.Entity;
46
-
47
- import javax.persistence.Id;
48
-
49
- import javax.persistence.Table;
50
-
51
-
52
-
53
- import lombok.Data;
54
-
55
-
56
-
57
- /**
58
-
59
- * ログインユーザのユーザ名、パスワードを格納するためのEntity
60
-
61
- * @author aoi
62
-
63
- *
64
-
65
- */
66
40
 
67
41
  @Entity
68
42
 
@@ -100,38 +74,238 @@
100
74
 
101
75
  }
102
76
 
77
+ UserDetailsインターフェースの実装コード
78
+
79
+ このコード内で「LoginUser」からidを取得する独自メソッドを設定しています。
80
+
81
+
82
+
83
+
84
+
85
+ ```ここに言語を入力
86
+
87
+ public class UserDetailsImpl implements UserDetails {
88
+
89
+
90
+
91
+ private static final long serialVersionUID = 1L;
92
+
93
+ private LoginUser user;
94
+
95
+
96
+
97
+ protected UserDetailsImpl() {};
98
+
99
+
100
+
101
+ public UserDetailsImpl(LoginUser user) {
102
+
103
+ this.user=user;
104
+
105
+
106
+
107
+ }
108
+
109
+
110
+
111
+ public int getUserId() {
112
+
113
+ return user.getUserId();
114
+
115
+ }
116
+
117
+
118
+
119
+
120
+
121
+ @Override
122
+
123
+ public Collection<? extends GrantedAuthority> getAuthorities() {
124
+
125
+ // TODO 自動生成されたメソッド・スタブ
126
+
127
+ return null;
128
+
129
+ }
130
+
131
+
132
+
133
+ @Override
134
+
135
+ public String getPassword() {
136
+
137
+ // TODO 自動生成されたメソッド・スタブ
138
+
139
+ return null;
140
+
141
+ }
142
+
143
+
144
+
145
+ @Override
146
+
147
+ public String getUsername() {
148
+
149
+ // TODO 自動生成されたメソッド・スタブ
150
+
151
+ return null;
152
+
153
+ }
154
+
155
+
156
+
157
+ @Override
158
+
159
+ public boolean isAccountNonExpired() {
160
+
161
+ // TODO 自動生成されたメソッド・スタブ
162
+
163
+ return false;
164
+
165
+ }
166
+
167
+
168
+
169
+ @Override
170
+
171
+ public boolean isAccountNonLocked() {
172
+
173
+ // TODO 自動生成されたメソッド・スタブ
174
+
175
+ return false;
176
+
177
+ }
178
+
179
+
180
+
181
+ @Override
182
+
183
+ public boolean isCredentialsNonExpired() {
184
+
185
+ // TODO 自動生成されたメソッド・スタブ
186
+
187
+ return false;
188
+
189
+ }
190
+
191
+
192
+
193
+ @Override
194
+
195
+ public boolean isEnabled() {
196
+
197
+ // TODO 自動生成されたメソッド・スタブ
198
+
199
+ return false;
200
+
201
+ }
202
+
203
+
204
+
205
+
206
+
207
+ }
208
+
103
209
  ```
104
210
 
105
-
106
-
211
+
212
+
107
- UserDetailsインターフェースの実装コード
213
+ controllerクラス内のメソッドに引数として「@AuthenticationPrincipal UserDetailsImpl userDetails」を設定しています。
108
-
214
+
109
- このコード内でLoginUser」からidを取得する独自メソッドを設定しています。
215
+ そしてSystem.out.println(userDetails.getUserId());でユーザーidを取得しようとしていますがnullが返ってきます
110
-
216
+
111
- ```ここに言語を入力
217
+ ```ここに言語を入力
218
+
219
+
220
+
221
+
222
+
112
-
223
+ @Controller
224
+
113
- package com.example.demo.model;
225
+ public class HomeController {
226
+
227
+
228
+
114
-
229
+ // インスタンスを作成しDIコンテナに格納。
230
+
115
-
231
+ @Autowired
116
-
232
+
117
- import java.util.Collection;
233
+ UserService userService;
234
+
235
+
236
+
118
-
237
+ //userListのアドレスにアクセスした際にGetメソッドを実行。
119
-
120
-
238
+
121
- import org.springframework.security.core.GrantedAuthority;
239
+ @GetMapping("/userList")
122
-
240
+
123
- import org.springframework.security.core.userdetails.UserDetails;
241
+ public String getUserList(Model model,@AuthenticationPrincipal UserDetailsImpl userDetails) {
242
+
243
+
244
+
245
+
246
+
124
-
247
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
248
+
125
-
249
+ //Principalからログインユーザの情報を取得
250
+
126
-
251
+ String userName = auth.getName();//ユーザー名は取得できます。
252
+
253
+ System.out.println(userDetails.getUserId()); // userIdは nullが返ってきます。
254
+
255
+
256
+
257
+ //@Autowiredで作成したインスタンスを元に、userServiceのメソッドを呼び出す。
258
+
259
+ List<User> userList = userService.selectMany();
260
+
261
+ //userServiceから受け取ったデータをView側に渡す。
262
+
127
- import com.example.demo.entity.LoginUser;
263
+ model.addAttribute("userList", userList);
264
+
128
-
265
+ model.addAttribute("userName", userName);
266
+
267
+
268
+
129
-
269
+ //template配下のファイル名を指定することでViewを呼び出せる。
270
+
271
+ return "userList";
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
+ UserDetailsインターフェースの実装コード内のisEnabledメソッドをtrueに変更しました。
300
+
301
+ ```ここに言語を入力
130
302
 
131
303
  public class UserDetailsImpl implements UserDetails {
132
304
 
133
305
 
134
306
 
307
+
308
+
135
309
  private static final long serialVersionUID = 1L;
136
310
 
137
311
  private LoginUser user;
@@ -198,156 +372,320 @@
198
372
 
199
373
 
200
374
 
201
- @Override
375
+ @Override
202
-
376
+
203
- public boolean isAccountNonExpired() {
377
+ public boolean isAccountNonExpired() {
204
-
378
+
205
- // TODO 自動生成されたメソッド・スタブ
379
+ // TODO 自動生成されたメソッド・スタブ
206
-
380
+
207
- return false;
381
+ return true;
382
+
383
+ }
384
+
385
+
386
+
387
+ @Override
388
+
389
+ public boolean isAccountNonLocked() {
390
+
391
+ // TODO 自動生成されたメソッド・スタブ
392
+
393
+ return true;
394
+
395
+ }
396
+
397
+
398
+
399
+ @Override
400
+
401
+ public boolean isCredentialsNonExpired() {
402
+
403
+ // TODO 自動生成されたメソッド・スタブ
404
+
405
+ return true;
406
+
407
+ }
408
+
409
+
410
+
411
+ @Override
412
+
413
+ public boolean isEnabled() {
414
+
415
+ // TODO 自動生成されたメソッド・スタブ
416
+
417
+ return true;
418
+
419
+ }
420
+
421
+
422
+
423
+ ```
424
+
425
+
426
+
427
+ UserDetailsServiceインターフェースの実装クラス
428
+
429
+
430
+
431
+ ```ここに言語を入力
432
+
433
+
434
+
435
+ @Service
436
+
437
+ public class UserDetailsServiceImpl implements UserDetailsService{
438
+
439
+
440
+
441
+
442
+
443
+ @Autowired
444
+
445
+ private LoginUserDao userDao;
446
+
447
+
448
+
449
+
450
+
451
+ @Override
452
+
453
+ public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
454
+
455
+
456
+
457
+ LoginUser user = userDao.findUser(userName);
458
+
459
+
460
+
461
+ if (user == null) {
462
+
463
+
464
+
465
+
466
+
467
+ throw new UsernameNotFoundException("User" + userName + "was not found in the database");
468
+
469
+ }
470
+
471
+
472
+
473
+ List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
474
+
475
+ GrantedAuthority authority = new SimpleGrantedAuthority("USER");
476
+
477
+
478
+
479
+ grantList.add(authority);
480
+
481
+
482
+
483
+ //rawDataのパスワードは渡すことができないので、暗号化
484
+
485
+ BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
486
+
487
+
488
+
489
+ //UserDetailsはインタフェースなのでUserクラスのコンストラクタで生成したユーザオブジェクトをキャスト
490
+
491
+ UserDetails userDetails = (UserDetails)new User(user.getUserName(), encoder.encode(user.getPassword()),grantList);
492
+
493
+
494
+
495
+ return userDetails;
496
+
497
+ }
498
+
499
+
500
+
501
+ }
502
+
503
+ ```
504
+
505
+ セキュリティコンフィグレーションクラス
506
+
507
+
508
+
509
+ ```ここに言語を入力
510
+
511
+
512
+
513
+ @Configuration
514
+
515
+ @EnableWebSecurity
516
+
517
+ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
518
+
519
+
520
+
521
+ @Autowired
522
+
523
+ private UserDetailsServiceImpl userDetailsService;
524
+
525
+
526
+
527
+ //フォームの値と比較するDBから取得したパスワードは暗号化されているのでフォームの値も暗号化するために利用
528
+
529
+ @Bean
530
+
531
+ public BCryptPasswordEncoder passwordEncoder() {
532
+
533
+ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
534
+
535
+ return bCryptPasswordEncoder;
536
+
537
+ }
538
+
539
+
540
+
541
+ /**
542
+
543
+ * 認可設定を無視するリクエストを設定
544
+
545
+ * 静的リソース(image,javascript,css)を認可処理の対象から除外する
546
+
547
+ */
548
+
549
+ @Override
550
+
551
+ public void configure(WebSecurity web) throws Exception {
552
+
553
+ web.ignoring().antMatchers(
554
+
555
+ "/images/**",
556
+
557
+ "/css/**",
558
+
559
+ "/javascript/**"
560
+
561
+ );
562
+
563
+ }
564
+
565
+
566
+
567
+ /**
568
+
569
+ * 認証・認可の情報を設定する
570
+
571
+ * 画面遷移のURL・パラメータを取得するname属性の値を設定
572
+
573
+ * SpringSecurityのconfigureメソッドをオーバーライドしています。
574
+
575
+ */
576
+
577
+ @Override
578
+
579
+ protected void configure(HttpSecurity http) throws Exception {
580
+
581
+ http
582
+
583
+ .authorizeRequests()
584
+
585
+ .antMatchers("/", "/home").permitAll() // アクセス制限のないURL
586
+
587
+ .anyRequest().authenticated()
588
+
589
+ .and()
590
+
591
+ .formLogin()
592
+
593
+ .loginPage("/login") //ログインページはコントローラを経由しないのでViewNameとの紐付けが必要
594
+
595
+ .loginProcessingUrl("/sign_in") //フォームのSubmitURL、このURLへリクエストが送られると認証処理が実行される
596
+
597
+ .usernameParameter("username") //リクエストパラメータのname属性を明示
598
+
599
+ .passwordParameter("password")
600
+
601
+ .defaultSuccessUrl("/userList", true) //認証が成功した際に遷移するURL
602
+
603
+ .failureUrl("/login?error") //認証が失敗した際に遷移するURL
604
+
605
+ .permitAll() //どのユーザでも接続できる。
606
+
607
+ .and()
608
+
609
+ .logout()
610
+
611
+ .logoutUrl("/logout")
612
+
613
+ .logoutSuccessUrl("/login?logout")
614
+
615
+ .permitAll();
616
+
617
+ }
618
+
619
+
620
+
621
+
622
+
623
+ @Autowired
624
+
625
+ public void configure(AuthenticationManagerBuilder auth) throws Exception{
626
+
627
+ auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
628
+
629
+ }
630
+
631
+
632
+
633
+ }
634
+
635
+ ```
636
+
637
+ mavenではなくてgradleを使用しています。
638
+
639
+ build gradle
640
+
641
+
642
+
643
+ ```ここに言語を入力
644
+
645
+
646
+
647
+
648
+
649
+ dependencies {
650
+
651
+ compile('org.springframework.boot:spring-boot-starter-data-jpa')
652
+
653
+ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
654
+
655
+ implementation 'org.springframework.boot:spring-boot-starter-web'
656
+
657
+ compileOnly 'org.projectlombok:lombok'
658
+
659
+ developmentOnly 'org.springframework.boot:spring-boot-devtools'
660
+
661
+ runtimeOnly 'mysql:mysql-connector-java'
662
+
663
+ annotationProcessor 'org.projectlombok:lombok'
664
+
665
+ implementation 'org.springframework.boot:spring-boot-starter-security'
666
+
667
+ // https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5
668
+
669
+ compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity5', version: '3.0.4.RELEASE'
670
+
671
+ // https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api
672
+
673
+ compile group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
674
+
675
+ testImplementation('org.springframework.boot:spring-boot-starter-test') {
676
+
677
+ exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
208
678
 
209
679
  }
210
680
 
211
-
212
-
213
- @Override
214
-
215
- public boolean isAccountNonLocked() {
216
-
217
- // TODO 自動生成されたメソッド・スタブ
218
-
219
- return false;
220
-
221
- }
222
-
223
-
224
-
225
- @Override
226
-
227
- public boolean isCredentialsNonExpired() {
228
-
229
- // TODO 自動生成されたメソッド・スタブ
230
-
231
- return false;
232
-
233
- }
234
-
235
-
236
-
237
- @Override
238
-
239
- public boolean isEnabled() {
240
-
241
- // TODO 自動生成されたメソッド・スタブ
242
-
243
- return false;
244
-
245
- }
246
-
247
-
248
-
249
-
250
-
251
681
  }
252
682
 
683
+
684
+
685
+
686
+
253
687
  ```
254
688
 
255
689
 
256
690
 
257
- controllerクラス内のメソッドに引数として「@AuthenticationPrincipal UserDetailsImpl userDetails」を設定しています。
258
-
259
- そして「System.out.println(userDetails.getUserId());」でユーザーidを取得しようとしていますがnullが返ってきます。
260
-
261
- ```ここに言語を入力
262
-
263
- package com.example.demo.controller;
264
-
265
-
266
-
267
- import java.util.List;
268
-
269
-
270
-
271
- import org.springframework.beans.factory.annotation.Autowired;
272
-
273
- import org.springframework.security.core.Authentication;
274
-
275
- import org.springframework.security.core.annotation.AuthenticationPrincipal;
276
-
277
- import org.springframework.security.core.context.SecurityContextHolder;
278
-
279
- import org.springframework.stereotype.Controller;
280
-
281
- import org.springframework.ui.Model;
282
-
283
- import org.springframework.web.bind.annotation.GetMapping;
284
-
285
-
286
-
287
- import com.example.demo.model.User;
288
-
289
- import com.example.demo.model.UserDetailsImpl;
290
-
291
- import com.example.demo.service.UserService;
292
-
293
-
294
-
295
- @Controller
296
-
297
- public class HomeController {
298
-
299
-
300
-
301
- // インスタンスを作成しDIコンテナに格納。
302
-
303
- @Autowired
304
-
305
- UserService userService;
306
-
307
-
308
-
309
- //userListのアドレスにアクセスした際にGetメソッドを実行。
310
-
311
- @GetMapping("/userList")
312
-
313
- public String getUserList(Model model,@AuthenticationPrincipal UserDetailsImpl userDetails) {
314
-
315
-
316
-
317
-
318
-
319
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
320
-
321
- //Principalからログインユーザの情報を取得
322
-
323
- String userName = auth.getName();//ユーザー名は取得できます。
324
-
325
- System.out.println(userDetails.getUserId()); // userIdは nullが返ってきます。
326
-
327
-
328
-
329
- //@Autowiredで作成したインスタンスを元に、userServiceのメソッドを呼び出す。
330
-
331
- List<User> userList = userService.selectMany();
332
-
333
- //userServiceから受け取ったデータをView側に渡す。
334
-
335
- model.addAttribute("userList", userList);
336
-
337
- model.addAttribute("userName", userName);
338
-
339
-
340
-
341
- //template配下のファイル名を指定することでViewを呼び出せる。
342
-
343
- return "userList";
344
-
345
- }
346
-
347
- }
348
-
349
- ```
350
-
351
- 何が原因かわからず詰まっております。
352
-
353
- 何卒よろくお願たします。
691
+ 他のコードも必要でたら追記いたします。