teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

3

ユーザ名とパスワードを追記

2020/06/16 21:42

投稿

waito
waito

スコア23

title CHANGED
File without changes
body CHANGED
@@ -191,6 +191,7 @@
191
191
 
192
192
  その他のクラスはGitHubにソースを配置したので、
193
193
  必要であればご確認をお願い致します。
194
+ ウェブアプリのユーザ名とパスワードはそれぞれuser1とdemoです。
194
195
 
195
196
  [https://github.com/uekiGityuto/test-session-control](https://github.com/uekiGityuto/test-session-control)
196
197
 

2

不要な処理のコメントアウト

2020/06/16 21:42

投稿

waito
waito

スコア23

title CHANGED
File without changes
body CHANGED
@@ -76,7 +76,7 @@
76
76
 
77
77
  ここからは予想なのですが、[この記事](https://qiita.com/rubytomato@github/items/a9a19f4a1cd5d732e5f8)によると、
78
78
  多重ログインチェックを機能させるためには、UserDetailsを実装したクラスの中で、
79
- equalsとhashCodeメソッドのオーバーライドを適切に行う必要らしく、
79
+ equalsとhashCodeメソッドのオーバーライドを適切に行うことが必要らしく、
80
80
  それが出来ていないのではないかと考えています。
81
81
 
82
82
  その観点から考えたのですが、結局何が問題か分からず、アドバイスをお願い致します。
@@ -158,13 +158,12 @@
158
158
  this.user = user;
159
159
  }
160
160
 
161
- public User getUser() {
162
- return user;
163
- }
164
-
165
- /*
166
- * lombokを使わずに実装してみた
161
+ /* lombokを使わずに実装してみた
167
162
  *
163
+ * public User getUser() {
164
+ * return user;
165
+ * }
166
+ *
168
167
  * @Override
169
168
  * public int hashCode() {
170
169
  * return user.getName().hashCode();

1

原因を絞り込めましたので追記しました。

2020/06/16 18:05

投稿

waito
waito

スコア23

title CHANGED
File without changes
body CHANGED
@@ -63,8 +63,141 @@
63
63
 
64
64
  何か気づくことがあればアドバイスをお願い致します。
65
65
 
66
+ ## 追記
67
+ 問題のプロジェクトとは別に、
68
+ 多重ログイン禁止処理を確かめるためのプロジェクトを新規に作成して試してみました。
69
+
70
+ すると、WebSecurityConfigurerAdapterを継承したクラスに、
71
+ 上記と同様、最大セッション数を1とするコードを書くと2重ログインを禁止出来ました。
72
+
73
+ そこから少しずつ、問題のプロジェクトに近づけていくと、
74
+ ログインに使用しているUSERテーブルのNAMEカラムを外部キーにもつMUTTERテーブルを作成し、
75
+ USERテーブルと関連性をもたせたタイミングで2重ログインが禁止できなくなりました。
76
+
77
+ ここからは予想なのですが、[この記事](https://qiita.com/rubytomato@github/items/a9a19f4a1cd5d732e5f8)によると、
78
+ 多重ログインチェックを機能させるためには、UserDetailsを実装したクラスの中で、
79
+ equalsとhashCodeメソッドのオーバーライドを適切に行う必要らしく、
80
+ それが出来ていないのではないかと考えています。
81
+
82
+ その観点から考えたのですが、結局何が問題か分からず、アドバイスをお願い致します。
83
+ なお、DB操作にはJPAを利用しています。
84
+
85
+ [Userエンティティクラス]
86
+ ```Java
87
+ package sample.spring.domain;
88
+
89
+ import java.io.Serializable;
90
+ import java.util.List;
91
+
92
+ import javax.persistence.CascadeType;
93
+ import javax.persistence.Column;
94
+ import javax.persistence.Entity;
95
+ import javax.persistence.FetchType;
96
+ import javax.persistence.GeneratedValue;
97
+ import javax.persistence.GenerationType;
98
+ import javax.persistence.Id;
99
+ import javax.persistence.OneToMany;
100
+ import javax.persistence.Table;
101
+
102
+ import com.fasterxml.jackson.annotation.JsonIgnore;
103
+
104
+ import lombok.AllArgsConstructor;
105
+ import lombok.Data;
106
+ import lombok.NoArgsConstructor;
107
+ import lombok.ToString;
108
+
109
+ @Entity
110
+ @Table(name = "USER")
111
+ @Data
112
+ @NoArgsConstructor
113
+ @AllArgsConstructor
114
+ @ToString(exclude = "mutters")
115
+ public class User implements Serializable {
116
+ private static final long serialVersionUID = 1L;
117
+
118
+ @Id
119
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
120
+ @Column(name = "USER_ID")
121
+ private Integer Id;
122
+
123
+ @Column(unique = true, nullable = false, name = "NAME", length = 64)
124
+ private String name;
125
+
126
+ @Column(nullable = false, name = "PASS", length = 80)
127
+ @JsonIgnore
128
+ private String pass;
129
+
130
+ // 以下をコメントアウトすると2重ログインが禁止出来る
131
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
132
+ private List<Mutter> mutters;
133
+
134
+ }
135
+ ```
136
+
137
+ [UserDetailsを実装したUserクラスを継承したクラス]
138
+ ```Java
139
+ package sample.spring.service;
140
+
141
+ import java.util.Collection;
142
+
143
+ import org.springframework.security.core.GrantedAuthority;
144
+
145
+ import sample.spring.domain.User;
146
+
147
+ import lombok.Data;
148
+ import lombok.EqualsAndHashCode;
149
+
150
+ @Data
151
+ @EqualsAndHashCode(callSuper = true)
152
+ public class LoginUserDetails extends org.springframework.security.core.userdetails.User {
153
+ private static final long serialVersionUID = 1L;
154
+ private final User user;
155
+
156
+ public LoginUserDetails(User user, Collection<GrantedAuthority> authorities) {
157
+ super(user.getName(), user.getPass(), authorities);
158
+ this.user = user;
159
+ }
160
+
161
+ public User getUser() {
162
+ return user;
163
+ }
164
+
165
+ /*
166
+ * lombokを使わずに実装してみた
167
+ *
168
+ * @Override
169
+ * public int hashCode() {
170
+ * return user.getName().hashCode();
171
+ * }
172
+ *
173
+ * @Override
174
+ * public boolean equals(Object rhs) {
175
+ * if (rhs instanceof User) {
176
+ * return user.getName().equals(((LoginUserDetails) rhs).user.getName()); }
177
+ * return false;
178
+ * }
179
+ *
180
+ * @Override
181
+ * public String toString(){
182
+ * StringBuilder sb = new StringBuilder();
183
+ * sb.append("Username: ").append(this.user.getName()).append("; ");
184
+ * sb.append("Password: [PROTECTED]; ");
185
+ *
186
+ * return sb.toString();
187
+ * }
188
+ */
189
+
190
+ }
191
+ ```
192
+
193
+ その他のクラスはGitHubにソースを配置したので、
194
+ 必要であればご確認をお願い致します。
195
+
196
+ [https://github.com/uekiGityuto/test-session-control](https://github.com/uekiGityuto/test-session-control)
197
+
198
+
66
199
  ## 補足
67
- 上記で省略していたSecurityConfigの全量を書きます。
200
+ 上記で省略していた問題のあるプロジェクトで使用しているSecurityConfigの全量す。
68
201
 
69
202
  ```Java
70
203
  package com.example;