欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

SpringSecurityRememberme使用及原理是什么

SpringSecurityRememberme使用及原理是什么,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

創(chuàng)新新互聯(lián),憑借十多年的成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),本著真心·誠心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有上1000+案例。做網(wǎng)站建設(shè),選成都創(chuàng)新互聯(lián)公司

Remember me功能就是勾選"記住我"后,一次登錄,后面在有效期內(nèi)免登錄。

先看具體配置:

pom文件:

<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-security</artifactId></dependency>

Security的配置:

@Autowired  private UserDetailsService myUserDetailServiceImpl; // 用戶信息服務(wù)  @Autowired  private DataSource dataSource; // 數(shù)據(jù)源  @Override  protected void configure(HttpSecurity http) throws Exception {    // formLogin()是默認(rèn)的登錄表單頁,如果不配置 loginPage(url),則使用 spring security    // 默認(rèn)的登錄頁,如果配置了 loginPage()則使用自定義的登錄頁    http.formLogin() // 表單登錄        .loginPage(SecurityConst.AUTH_REQUIRE)        .loginProcessingUrl(SecurityConst.AUTH_FORM) // 登錄請求攔截的url,也就是form表單提交時(shí)指定的action        .successHandler(loginSuccessHandler)        .failureHandler(loginFailureHandler)        .and()      .rememberMe()        .userDetailsService(myUserDetailServiceImpl) // 設(shè)置userDetailsService        .tokenRepository(persistentTokenRepository()) // 設(shè)置數(shù)據(jù)訪問層        .tokenValiditySeconds(60 * 60) // 記住我的時(shí)間(秒)        .and()      .authorizeRequests() // 對請求授權(quán)        .antMatchers(SecurityConst.AUTH_REQUIRE, securityProperty.getBrowser().getLoginPage()).permitAll() // 允許所有人訪問login.html和自定義的登錄頁        .anyRequest() // 任何請求        .authenticated()// 需要身份認(rèn)證        .and()      .csrf().disable() // 關(guān)閉跨站偽造    ;  }  /**   * 持久化token   *    * Security中,默認(rèn)是使用PersistentTokenRepository的子類InMemoryTokenRepositoryImpl,將token放在內(nèi)存中   * 如果使用JdbcTokenRepositoryImpl,會創(chuàng)建表persistent_logins,將token持久化到數(shù)據(jù)庫   */  @Bean  public PersistentTokenRepository persistentTokenRepository() {    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();    tokenRepository.setDataSource(dataSource); // 設(shè)置數(shù)據(jù)源//    tokenRepository.setCreateTableOnStartup(true); // 啟動(dòng)創(chuàng)建表,創(chuàng)建成功后注釋掉    return tokenRepository;  }

上面的myUserDetailServiceImpl是自己實(shí)現(xiàn)的UserDetailsService接口,dataSource會自動(dòng)讀取數(shù)據(jù)庫配置。過期時(shí)間設(shè)置的3600秒,即一個(gè)小時(shí)

在登錄頁面加一行(name必須是remeber-me):

"記住我"基本原理:

1、第一次發(fā)送認(rèn)證請求,會被UsernamePasswordAuthenticationFilter攔截,然后身份認(rèn)證。

認(rèn)證成功后,在AbstracAuthenticationProcessingFilter中,有個(gè)RememberMeServices接口。

該接口默認(rèn)實(shí)現(xiàn)類是NullRememberMeServices,這里會調(diào)用另一個(gè)實(shí)現(xiàn)抽象類AbstractRememberMeServices

// ...  private RememberMeServices rememberMeServices = new NullRememberMeServices();  protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,      Authentication authResult) throws IOException, ServletException {    // ...    SecurityContextHolder.getContext().setAuthentication(authResult);    // 登錄成功后,調(diào)用RememberMeServices保存Token相關(guān)信息    rememberMeServices.loginSuccess(request, response, authResult);    // ...  }

2、調(diào)用AbstractRememberMeServices的loginSuccess方法。

可以看到如果request中name為"remember-me"為true時(shí),才會調(diào)用下面的onLoginSuccess()方法。這也是為什么上面登錄頁中的表單,name必須是"remember-me"的原因:

3、在Security中配置了rememberMe()之后, 會由PersistentTokenBasedRememberMeServices去實(shí)現(xiàn)父類AbstractRememberMeServices中的抽象方法。

在PersistentTokenBasedRememberMeServices中,有一個(gè)PersistentTokenRepository,會生成一個(gè)Token,并將這個(gè)Token寫到cookie里面返回瀏覽器。PersistentTokenRepository的默認(rèn)實(shí)現(xiàn)類是InMemoryTokenRepositoryImpl,該默認(rèn)實(shí)現(xiàn)類會將token保存到內(nèi)存中。這里我們配置了它的另一個(gè)實(shí)現(xiàn)類JdbcTokenRepositoryImpl,該類會將Token持久化到數(shù)據(jù)庫中

// ...  private PersistentTokenRepository tokenRepository = new InMemoryTokenRepositoryImpl();  protected void onLoginSuccess(HttpServletRequest request,      HttpServletResponse response, Authentication successfulAuthentication) {    String username = successfulAuthentication.getName();    logger.debug("Creating new persistent login for user " + username);    // 創(chuàng)建一個(gè)PersistentRememberMeToken    PersistentRememberMeToken persistentToken = new PersistentRememberMeToken(        username, generateSeriesData(), generateTokenData(), new Date());    try {      // 保存Token      tokenRepository.createNewToken(persistentToken);      // 將Token寫到Cookie中      addCookie(persistentToken, request, response);    }    catch (Exception e) {      logger.error("Failed to save persistent token ", e);    }  }

4、JdbcTokenRepositoryImpl將Token持久化到數(shù)據(jù)庫

/** The default SQL used by <tt>createNewToken</tt> */  public static final String DEF_INSERT_TOKEN_SQL = "insert into persistent_logins (username, series, token, last_used) values(?,?,?,?)";  public void createNewToken(PersistentRememberMeToken token) {    getJdbcTemplate().update(insertTokenSql, token.getUsername(), token.getSeries(),        token.getTokenValue(), token.getDate());  }

查看數(shù)據(jù)庫,可以看到往persistent_logins 中插入了一條數(shù)據(jù):

5、重啟服務(wù),發(fā)送第二次認(rèn)證請求,只會攜帶Cookie。

所以直接會被RememberMeAuthenticationFilter攔截,并且此時(shí)內(nèi)存中沒有認(rèn)證信息。

可以看到,此時(shí)的RememberMeServices是由PersistentTokenBasedRememberMeServices實(shí)現(xiàn)

6、在PersistentTokenBasedRememberMeServices中,調(diào)用processAutoLoginCookie方法,獲取用戶相關(guān)信息

protected UserDetails processAutoLoginCookie(String[] cookieTokens,      HttpServletRequest request, HttpServletResponse response) {    if (cookieTokens.length != 2) {      throw new InvalidCookieException("Cookie token did not contain " + 2          + " tokens, but contained '" + Arrays.asList(cookieTokens) + "'");    }    // 從Cookie中獲取Series和Token    final String presentedSeries = cookieTokens[0];    final String presentedToken = cookieTokens[1];     //在數(shù)據(jù)庫中,通過Series查詢PersistentRememberMeToken    PersistentRememberMeToken token = tokenRepository        .getTokenForSeries(presentedSeries);    if (token == null) {      throw new RememberMeAuthenticationException(          "No persistent token found for series id: " + presentedSeries);    }    // 校驗(yàn)數(shù)據(jù)庫中Token和Cookie中的Token是否相同    if (!presentedToken.equals(token.getTokenValue())) {      tokenRepository.removeUserTokens(token.getUsername());      throw new CookieTheftException(          messages.getMessage(              "PersistentTokenBasedRememberMeServices.cookieStolen",              "Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack."));    }    // 判斷Token是否超時(shí)    if (token.getDate().getTime() + getTokenValiditySeconds() * 1000L < System        .currentTimeMillis()) {      throw new RememberMeAuthenticationException("Remember-me login has expired");    }    if (logger.isDebugEnabled()) {      logger.debug("Refreshing persistent login token for user '"          + token.getUsername() + "', series '" + token.getSeries() + "'");    }        // 創(chuàng)建一個(gè)新的PersistentRememberMeToken    PersistentRememberMeToken newToken = new PersistentRememberMeToken(        token.getUsername(), token.getSeries(), generateTokenData(), new Date());    try {      //更新數(shù)據(jù)庫中Token      tokenRepository.updateToken(newToken.getSeries(), newToken.getTokenValue(),          newToken.getDate());      //重新寫到Cookie      addCookie(newToken, request, response);    }    catch (Exception e) {      logger.error("Failed to update token: ", e);      throw new RememberMeAuthenticationException(          "Autologin failed due to data access problem");    }    //調(diào)用UserDetailsService獲取用戶信息    return getUserDetailsService().loadUserByUsername(token.getUsername());  }

7、獲取用戶相關(guān)信息后,再調(diào)用AuthenticationManager去認(rèn)證授權(quán)

關(guān)于SpringSecurityRememberme使用及原理是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

網(wǎng)站名稱:SpringSecurityRememberme使用及原理是什么
當(dāng)前路徑:http://aaarwkj.com/article0/goopoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、ChatGPT、定制網(wǎng)站、App開發(fā)做網(wǎng)站、動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
国产熟女碰碰人人a久久| 麻豆AV一区二区三区久久| 国产黄片一区二区在线| 色悠悠粉嫩一区二区三区| 欧美精品一区二区三区在线| 免费爱爱视频在线观看| 麻豆精东传媒一区二区| 欧美精品日本一区二区| 国产精品主播自拍视频| 中文字幕在线精品乱码| 人妻精品中文字幕一区二区在线| 亚洲国产区男人的天堂| 欧美色精品人妻在线最新| 91欧美精品一区二区| 日韩精品亚洲一级在线观看| 在线国产偷拍自拍视频| 91青青草原免费观看| 亚洲国产日韩欧美在线播放| 中文字幕人妻中文av不卡专区| 美女午夜福利一区二区| 激情偷拍一区二区三区视频| 人妻少妇偷人精品免费看| 激情图区亚洲一区二区| 色自拍偷拍另类欧洲美女| 亚洲欧美一区二区中文字幕| 日韩黄色精品中文视频| 久久精品无人区乱码一区二区| 亚洲无线码一区国产欧美国日| 日韩高清精品视频在线| 国产精品 亚洲精品| 精品黄色大片不卡国产| 国产精品夜色一区二区三区不卡 | 亚洲免费av一区二区| 一本之道久久成人综合| 日韩电影在线播放中文字幕| 雪白肥臀视频一区二区三区| 传媒视频在线免费观看| 国产一级二级三级亚洲| 国产一区二区三区的网站| 国产成人精品久久久亚洲| 国产好大好爽在线免费观看|