76

Web アプリケーションで春のセキュリティを使用していますが、プログラムにログインしているすべてのユーザーのリストを取得したいと考えています。

そのリストにアクセスするにはどうすればよいですか? それらはすでに春のフレームワーク内のどこかに保持されていませんか? SecurityContextHolderSecurityContextRepositoryのように?

4

7 に答える 7

65

ログインしているすべてのユーザーのリストにアクセスするには、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>
于 2012-06-30T07:04:52.897 に答える
51

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

于 2014-11-27T16:55:18.767 に答える
10

私が間違っている場合は、私を修正してください。

@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);
                }
            }
        }
    }
}

それが役に立てば幸い。

于 2016-07-04T23:04:40.773 に答える