Heim > Java > javaLernprogramm > Wie SpringBoot Security Single Sign-out implementiert und alle Token löscht

Wie SpringBoot Security Single Sign-out implementiert und alle Token löscht

WBOY
Freigeben: 2023-05-14 13:43:11
nach vorne
2088 Leute haben es durchsucht

Anforderungen

  • A-, B- und C-Systeme melden sich über den SSO-Dienst an meldet sich aktiv ab. Die anderen beiden Systeme haben sich ebenfalls abgemeldet. Wird zum Parsen des Tokens verwendet

    Denn es wird mehrere Systeme geben, die Der Benutzer meldet sich an, daher verwendet der Wert die Redis-Liste Typ zum Speichern des Tokens
  • Stellen Sie die Gültigkeitszeit ein, um sicherzustellen, dass sie nicht kürzer als die maximale Gültigkeitszeit des Tokens in der Liste ist
  • <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>
    Nach dem Login kopieren

    oauth_access_token Verwenden Sie JdbcTokenStore Um Token zu speichern, müssen Sie eine neue Tabelle hinzufügen kenStore
  • tokenServices TokenStore hinzufügen

endpoints TokenServices hinzufügen

    @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;
        }
    }
    Nach dem Login kopieren
  • clear token

  • inherits SimpleUrlLogoutSuccessHandler

Benutzernamen abrufen. userName

  • Rufen Sie beim Anmelden die in Redis gespeicherte Token-Liste ab

  • Token-Zeichenfolge wird in OAuth3AccessToken konvertiert

  • TokenStore verwenden, um das Token zu löschen

  • 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;
    Nach dem Login kopieren
  • Das Problem der übermäßigen Abmeldezeit wurde behoben

    Szenario: Nachdem das Projekt eine Zeit lang ausgeführt wurde, wird festgestellt, dass das Die Abmeldezeit wird immer langsamer
Problem: Beim Debuggen wurde festgestellt, dass der Zeitaufwand hauptsächlich im Zeitraum des Löschens von Token liegt

@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)
        ;
    }
	...
}
Nach dem Login kopieren

Ursache: Mit der Zeit gibt es immer mehr Token in der Speichertabelle oauth_access_token ist ungewöhnlich groß geworden, daher ist die Löscheffizienz sehr schlecht

Lösung: Verwenden Sie einen anderen TokenStore oder löschen Sie die Tabellendaten von oauth_access_token

    Das obige ist der detaillierte Inhalt vonWie SpringBoot Security Single Sign-out implementiert und alle Token löscht. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:yisu.com
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage