Jadual Kandungan
Keperluan
Token rekod
Senario: Selepas projek telah berjalan untuk satu tempoh masa, didapati bahawa masa log keluar semakin perlahan dan semakin perlahan
Rumah Java javaTutorial Cara SpringBoot Security melaksanakan log keluar tunggal dan mengosongkan semua token

Cara SpringBoot Security melaksanakan log keluar tunggal dan mengosongkan semua token

May 14, 2023 pm 01:43 PM
token springboot security

Keperluan

  • Sistem A, B dan C boleh log masuk melalui perkhidmatan sso

  • Sistem A, B dan C memperoleh Atoken dan Btoken masing-masing , Ctoken tiga token

  • Selepas salah satu sistem log keluar secara aktif, dua sistem lain turut log keluar

  • Setakat ini semua Atoken dan Btoken , Ctoken tidak sah

Token rekod

fail pom memperkenalkan kebergantungan

  • Kebergantungan pangkalan data Redis

  • hutool: digunakan untuk menghuraikan token

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.13</version>
</dependency>
Salin selepas log masuk

kelas storan token melaksanakan AuthJdbcTokenStore

  • TokenStore>mewarisi JdbcToken>

  • Gunakan nama pengguna pengguna log masuk sebagai kunci Redis

  • Oleh kerana akan terdapat berbilang sistem di mana pengguna log masuk, nilai menggunakan Jenis senarai redis untuk menyimpan token

  • Tetapkan masa sah untuk memastikan bahawa ia tidak kurang daripada masa sah maksimum token dalam senarai

  • @Component
    public class AuthJdbcTokenStore extends JdbcTokenStore {
        public static final String USER_HAVE_TOKEN = "user-tokens:";
        @Resource
        RedisTemplate redisTemplate;
        public AuthJdbcTokenStore(DataSource connectionFactory) {
            super(connectionFactory);
        }
        @Override
        public void storeAccessToken(OAuth3AccessToken token, OAuth3Authentication authentication) {
            super.storeAccessToken(token, authentication);
            if (Optional.ofNullable(authentication.getUserAuthentication()).isPresent()) {
                User user = (User) authentication.getUserAuthentication().getPrincipal();
                String userTokensKey = USER_HAVE_TOKEN + user.getUsername();
                String tokenValue = token.getValue();
                redisTemplate.opsForList().leftPush(userTokensKey, tokenValue);
                Long seconds = redisTemplate.opsForValue().getOperations().getExpire(userTokensKey);
                Long tokenExpTime = getExpTime(tokenValue);
                Long expTime = seconds < tokenExpTime ? tokenExpTime : seconds;
                redisTemplate.expire(userTokensKey, expTime, TimeUnit.SECONDS);
            }
        }
        private long getExpTime(String accessToken) {
            JWT jwt = JWTUtil.parseToken(accessToken);
            cn.hutool.json.JSONObject jsonObject = jwt.getPayload().getClaimsJson();
            long nowTime = Instant.now().getEpochSecond();
            long expEndTime = jsonObject.getLong("exp");
            long expTime = (expEndTime - nowTime);
            return expTime;
        }
    }
    Salin selepas log masuk
oauth_access_token Menggunakan JdbcTokenStore untuk menyimpan token memerlukan jadual baharu

CREATE TABLE `oauth_access_token` (
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `token_id` varchar(255) DEFAULT NULL,
  `token` blob,
  `authentication_id` varchar(255) DEFAULT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  `client_id` varchar(255) DEFAULT NULL,
  `authentication` blob,
  `refresh_token` varchar(255) DEFAULT NULL,
  UNIQUE KEY `authentication_id` (`authentication_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
Salin selepas log masuk

AuthorizationServerConfigurerAdapter menggunakan AuthJdbcTokenStore untuk storan token

  • Melalui kaedah Pembinaan Jbc. dalam DataSource

  • Buat TokenStore Gunakan AuthJdbcTokenStore untuk melaksanakan

  • tokenServices Tambah TokenStore

  • <🎜 Tambah tokenServices

  • @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
        @Autowired
        private DataSource dataSource;
    	...
        @Bean
        public TokenStore tokenStore() {
            JdbcTokenStore tokenStore = new AuthJdbcTokenStore(dataSource);
            return tokenStore;
        }
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            DefaultTokenServices tokenServices = new DefaultTokenServices();
            tokenServices.setTokenStore(tokenStore());
            endpoints
                    .authenticationManager(authenticationManager)
                    .tokenServices(tokenServices)
                    .accessTokenConverter(converter)
            ;
        }
    	...
    }
    Salin selepas log masuk
Kosongkan token

  • Warisi SimpleUrlLogoutSuccessHandler

  • Dapatkan nama pengguna

  • Dapatkan senarai token yang disimpan dalam Redis semasa log masuk
  • Rentetan token ditukar kepada OAuth3AccessToken
  • Gunakan tokenStore untuk memadam token
  • @Component
    public class AuthLogoutSuccessHandler1 extends SimpleUrlLogoutSuccessHandler {
        String USER_HAVE_TOKEN = AuthJdbcTokenStore.USER_HAVE_TOKEN;
        @Resource
        RedisTemplate redisTemplate;
        @Resource
        TokenStore tokenStore;
        @Override
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            if (!Objects.isNull(authentication)) {
                String userName = authentication.getName();
                String userTokensKey = USER_HAVE_TOKEN + userName;
                Long size = redisTemplate.opsForList().size(userTokensKey);
                List&lt;String&gt; list = redisTemplate.opsForList().range(userTokensKey, 0, size);
                for (String tokenValue : list) {
                    OAuth3AccessToken token = tokenStore.readAccessToken(tokenValue);
                    if (Objects.nonNull(token)) {
                        tokenStore.removeAccessToken(token);
                    }
                }
                redisTemplate.delete(userTokensKey);
                super.handle(request, response, authentication);
            }
        }
    }
    Salin selepas log masuk
  • Untuk menyelesaikan masa log keluar Terlalu lama

Senario: Selepas projek telah berjalan untuk satu tempoh masa, didapati bahawa masa log keluar semakin perlahan dan semakin perlahan

Masalah: Melalui penyahpepijatan, didapati bahawa memakan masa adalah terutamanya dalam tempoh pemadaman token

tokenStore.removeAccessToken(token);
Salin selepas log masuk

Sebab: Semakin masa berlalu, semakin banyak dan lebih banyak token dan jadual storan token oauth_access_token menjadi luar biasa besar, jadi kecekapan pemadaman sangat lemah

Penyelesaian: Gunakan TokenStore lain, atau kosongkan data jadual oauth_access_token

Atas ialah kandungan terperinci Cara SpringBoot Security melaksanakan log keluar tunggal dan mengosongkan semua token. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Tag artikel panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

17 cara untuk menyelesaikan skrin biru kernel_security_check_failure 17 cara untuk menyelesaikan skrin biru kernel_security_check_failure Feb 12, 2024 pm 08:51 PM

17 cara untuk menyelesaikan skrin biru kernel_security_check_failure

Bagaimana Springboot menyepadukan Jasypt untuk melaksanakan penyulitan fail konfigurasi Bagaimana Springboot menyepadukan Jasypt untuk melaksanakan penyulitan fail konfigurasi Jun 01, 2023 am 08:55 AM

Bagaimana Springboot menyepadukan Jasypt untuk melaksanakan penyulitan fail konfigurasi

Bagaimana untuk menyelesaikan masalah token log masuk tidak sah Bagaimana untuk menyelesaikan masalah token log masuk tidak sah Sep 14, 2023 am 10:57 AM

Bagaimana untuk menyelesaikan masalah token log masuk tidak sah

Cara menggunakan Redis untuk melaksanakan kunci teragih dalam SpringBoot Cara menggunakan Redis untuk melaksanakan kunci teragih dalam SpringBoot Jun 03, 2023 am 08:16 AM

Cara menggunakan Redis untuk melaksanakan kunci teragih dalam SpringBoot

Bagaimana untuk menyelesaikan masalah bahawa springboot tidak boleh mengakses fail selepas membacanya ke dalam pakej balang Bagaimana untuk menyelesaikan masalah bahawa springboot tidak boleh mengakses fail selepas membacanya ke dalam pakej balang Jun 03, 2023 pm 04:38 PM

Bagaimana untuk menyelesaikan masalah bahawa springboot tidak boleh mengakses fail selepas membacanya ke dalam pakej balang

Analisis perbandingan dan perbezaan antara SpringBoot dan SpringMVC Analisis perbandingan dan perbezaan antara SpringBoot dan SpringMVC Dec 29, 2023 am 11:02 AM

Analisis perbandingan dan perbezaan antara SpringBoot dan SpringMVC

Perkara yang perlu dilakukan jika token log masuk tidak sah Perkara yang perlu dilakukan jika token log masuk tidak sah Sep 14, 2023 am 11:33 AM

Perkara yang perlu dilakukan jika token log masuk tidak sah

Bagaimana SpringBoot menyesuaikan Redis untuk melaksanakan penyirian cache Bagaimana SpringBoot menyesuaikan Redis untuk melaksanakan penyirian cache Jun 03, 2023 am 11:32 AM

Bagaimana SpringBoot menyesuaikan Redis untuk melaksanakan penyirian cache

See all articles