Web アプリケーションで春のセキュリティを使用していますが、プログラムにログインしているすべてのユーザーのリストを取得したいと考えています。
そのリストにアクセスするにはどうすればよいですか? それらはすでに春のフレームワーク内のどこかに保持されていませんか? SecurityContextHolderやSecurityContextRepositoryのように?
Web アプリケーションで春のセキュリティを使用していますが、プログラムにログインしているすべてのユーザーのリストを取得したいと考えています。
そのリストにアクセスするにはどうすればよいですか? それらはすでに春のフレームワーク内のどこかに保持されていませんか? SecurityContextHolderやSecurityContextRepositoryのように?
ログインしているすべてのユーザーのリストにアクセスするには、SessionRegistry インスタンスを Bean に注入する必要があります。
@Autowired
@Qualifier("sessionRegistry")
private SessionRegistry sessionRegistry;
そして、注入された SessionRegistry を使用して、すべてのプリンシパルのリストにアクセスできます。
List<Object> principals = sessionRegistry.getAllPrincipals();
List<String> usersNamesList = new ArrayList<String>();
for (Object principal: principals) {
if (principal instanceof User) {
usersNamesList.add(((User) principal).getUsername());
}
}
ただし、セッション レジストリを注入する前に、spring-security.xml でセッション管理部分を定義する必要があり ( Spring Security リファレンス ドキュメントのセッション管理セクションを参照)、同時実行制御セクションでセッション レジストリ オブジェクトのエイリアスを設定する必要があります ( session-registry- alias ) によって注入します。
<security:http access-denied-page="/error403.jsp" use-expressions="true" auto-config="false">
<security:session-management session-fixation-protection="migrateSession" session-authentication-error-url="/login.jsp?authFailed=true">
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.html" session-registry-alias="sessionRegistry"/>
</security:session-management>
...
</security:http>
JavaConfig では、次のようになります。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(final HttpSecurity http) throws Exception {
// ...
http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry());
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
}
}
呼び出しコードは次のようになります。
public class UserController {
@Autowired
private SessionRegistry sessionRegistry;
public void listLoggedInUsers() {
final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
for(final Object principal : allPrincipals) {
if(principal instanceof SecurityUser) {
final SecurityUser user = (SecurityUser) principal;
// Do something with user
System.out.println(user);
}
}
}
}
SecurityUser
を実装する私自身のクラスであることに注意してくださいUserDetails
。
私が間違っている場合は、私を修正してください。
@Adamの答えは不完全だと思います。リストですでに期限切れになっているセッションが再び表示されていることに気付きました。
public class UserController {
@Autowired
private SessionRegistry sessionRegistry;
public void listLoggedInUsers() {
final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
for (final Object principal : allPrincipals) {
if (principal instanceof SecurityUser) {
final SecurityUser user = (SecurityUser) principal;
List<SessionInformation> activeUserSessions =
sessionRegistry.getAllSessions(principal,
/* includeExpiredSessions */ false); // Should not return null;
if (!activeUserSessions.isEmpty()) {
// Do something with user
System.out.println(user);
}
}
}
}
}
それが役に立てば幸い。