2017-03-29 27 views
10

私は赤ちゃんに新しいです。私はこのチュートリアルにしたがって、HttpSessionをredisで使用しました。spring-boot redis:ユーザーのすべてのセッションを無効にする方法は?

https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html

今、私のアプリケーションは、オプション「すべてのデバイスからサインアウト」を有します。これをクリックすると、そのユーザーのすべてのセッションを削除または無効にするにはどうすればよいですか?

また、ユーザーがパスワードを変更した場合、現在のセッション以外のすべてのセッションを無効にするにはどうすればよいですか?

編集:

私はセッションのレジストリを使用してみました。

@Autowired 
private FindByIndexNameSessionRepository sessionRepository; 

@Autowired 
FindByIndexNameSessionRepository<? extends ExpiringSession> sessions; 

@RequestMapping(value = "/logoutalldevices", method = RequestMethod.GET) 
public Response test(HttpServletRequest request, HttpServletResponse response) throws Exception { 

    SpringSessionBackedSessionRegistry sessionRegistry = new SpringSessionBackedSessionRegistry(sessionRepository); 

    Collection<? extends ExpiringSession> usersSessions = sessions 
      .findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "myUserId") 
      .values(); 

    usersSessions.forEach((temp) -> { 
     String sessionId = temp.getId(); 
     // sessionRegistry.removeSessionInformation(sessionId); 
     SessionInformation info = sessionRegistry.getSessionInformation(sessionId); 
     info.expireNow(); 
    }); 

    return Response.ok().build(); 
} 

ただし、redis dbからセッションを削除したり、無効にしているわけではありません。値 'true'を持つ 'sessionAttr:org.springframework.session.security.SpringSessionBackedSessionInformation.EXPIRED'という名前のセッションに新しい属性を追加しています。私はredistemplateを使用してDBのRedisからセッションを手動で削除しようとした

編集私は

HGETALL 'sessionid'

を行う際のRedisクライアントを使用してDBのRedisにこの新しいキーと値のペアを見ることができます。

@Autowired 
RedisTemplate<String, String> redisTemplate; 

--------- 

redisTemplate.delete("spring:session:sessions:" + sessionId); 
redisTemplate.delete("spring:session:sessions:expires:" + sessionId); 

これはほとんど動作します。 redis dbから値を削除しますが、キーは削除しません。

127.0.0.1:6379> keys * 
1) "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 
2) "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 
3) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:1" 
127.0.0.1:6379> hgetall spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7 
1) "lastAccessedTime" 
2) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01[R'\x15\xc1" 
127.0.0.1:6379> 

これは、lastAccessedTime時間以外のセッション内の他のすべてのキー値ペアを削除しました。私はコピーしてクライアントをRedisのと、キーがあり、実行するには、上記の2つのコマンドを貼り付ける場合は

1491731944.899711 [0 127.0.0.1:62816] "DEL" "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 
1491731944.899853 [0 127.0.0.1:62816] "DEL" "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 

:また

これは奇妙な一つは、これはredisTemplate.delete("key")が実行されRedisのモニタでは、私が見たログです削除されました。 keys *を実行するとキーが表示されません。その削除された時にキーが削除キーのためにこれを試してみてくださいRedisTemplate

127.0.0.1:6379> "DEL" "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 
(integer) 1 
127.0.0.1:6379> "DEL" "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7" 
(integer) 1 
127.0.0.1:6379> keys * 
1) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:1" 
127.0.0.1:6379> 
+0

春のセキュリティ設定を共有できますか? –

+0

私は設定を一切設定していません。 spring-boot-starter-securityの依存関係が追加されました。それでおしまい。何かを追加する必要はありますか? – HeisenBerg

+0

あなたは '// sessionRegistry.removeSessionInformation(sessionId);'をコメントしました。あなたの場合はどうなりましたか? –

答えて

4

redisデータベースからエントリを削除することを意味していない、それだけで追加しますあなたが正しく言及したようにセッションに期限切れの属性。

これはどのようにしてユーザーのセッションを無効にしますか?

はここでここでスニペット用ConcurrentSessionFilter

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
     throws IOException, ServletException { 
    HttpServletRequest request = (HttpServletRequest) req; 
    HttpServletResponse response = (HttpServletResponse) res; 

    HttpSession session = request.getSession(false); 

    if (session != null) { 
     SessionInformation info = sessionRegistry.getSessionInformation(session 
       .getId()); 

     if (info != null) { 
      if (info.isExpired()) { 
       // Expired - abort processing 
       doLogout(request, response); 

       String targetUrl = determineExpiredUrl(request, info); 

       if (targetUrl != null) { 
        redirectStrategy.sendRedirect(request, response, targetUrl); 

        return; 
       } 
       else { 
        response.getWriter().print(
          "This session has been expired (possibly due to multiple concurrent " 
            + "logins being attempted as the same user)."); 
        response.flushBuffer(); 
       } 

       return; 
      } 
      else { 
       // Non-expired - update last request date/time 
       sessionRegistry.refreshLastRequest(info.getSessionId()); 
      } 
     } 
    } 

    chain.doFilter(request, response); 
} 

乾杯がある .doFilter()方法はautomatically logging out

のトリックを行う場にConcurrentSessionFilter来ます!

+0

この方法で見つけた1つの問題は、期限切れのセッションがredis dbから削除されないことです。 – HeisenBerg

0

を使用して削除取得されていない理由を私は疑問に思う "redisTemplate.opsForValue()getOperations()(KEY)を削除します。。。"私は

SessionInformation.expireNow() 

を注意することは、ユーザー・セッションに

usersSessions.forEach((session) -> {   
     sessionRegistry.getSessionInformation(session.getId()).expireNow(); 
    }); 

代を無効にするためにyou are following the correct pathことをお知りになりたい

+0

同じ効果があります。キーを削除しません。 – HeisenBerg

関連する問題