javascript
使用Spring Security添加RememberMe身份验证
我在“ 將社交登錄添加到Jiwhiz博客”中提到,RememberMe功能不適用于Spring Social Security。 好吧,這是因?yàn)樵搼?yīng)用程序現(xiàn)在不通過(guò)用戶名和密碼對(duì)用戶進(jìn)行身份驗(yàn)證,并且完全取決于社交網(wǎng)站(例如Google,Facebook和Twitter)來(lái)完成此工作。 默認(rèn)的Spring Security配置無(wú)法處理這種情況。 Spring Security可能是所有Spring Portfolio項(xiàng)目中最復(fù)雜的軟件。 為了使一個(gè)非常簡(jiǎn)單的Web應(yīng)用程序具有安全性,大約需要正確設(shè)置10個(gè)過(guò)濾器。 為了簡(jiǎn)化應(yīng)用程序開(kāi)發(fā),Spring Security從2.0版開(kāi)始提供名稱空間配置,以自動(dòng)將所有必需的組件一起設(shè)置,因此開(kāi)發(fā)人員無(wú)需弄清楚細(xì)節(jié)。 除非您的應(yīng)用程序與傳統(tǒng)應(yīng)用程序不同,否則它對(duì)大多數(shù)Web應(yīng)用程序都非常有效。
在將網(wǎng)站登錄過(guò)程從用戶名密碼身份驗(yàn)證更改為不帶密碼的Spring Social Security之后 ,“記住我”的舊配置不再起作用。 Spring Security參考文檔幾乎沒(méi)有關(guān)于Remember-Me Authentication的解釋,所以我買了Spring Security項(xiàng)目負(fù)責(zé)人Rob Winch編寫的書(shū)Spring Security 3.1 。 這本書(shū)整整一章都在討論“記住我”服務(wù),它對(duì)我在Spring Security中如何理解我的工作很有幫助。 讀完本書(shū)后,我覺(jué)得閱讀Spring Security源代碼要容易得多,并且閱讀源代碼總是很有趣的。
由于我沒(méi)有存儲(chǔ)用戶帳戶的密碼,因此默認(rèn)的TokenBasedRememberMeServices無(wú)法與我的應(yīng)用程序一起使用,并且我也不想創(chuàng)建自己的RememberMeServices-太多的工作。 幸運(yùn)的是,還有另一種持久令牌方法 ,即將令牌存儲(chǔ)到數(shù)據(jù)庫(kù)中并比較cookie中的令牌。 我需要的是使用PersistentTokenRepository在我的應(yīng)用程序中自定義PersistentTokenBasedRememberMeServices來(lái)存儲(chǔ)令牌。 Spring Security提供了PersistentTokenRepository的JDBC實(shí)現(xiàn),我發(fā)現(xiàn)在閱讀源代碼之后編寫自己的MongoDB實(shí)現(xiàn)非常簡(jiǎn)單。
第一步是將PersistentRememberMeToken數(shù)據(jù)存儲(chǔ)到MongoDB。 我需要為其添加一個(gè)域?qū)嶓w類:
@Document(collection = 'RememberMeToken') public class RememberMeToken extends BaseEntity{private String username;@Indexedprivate String series;private String tokenValue;private Date date;... // getter/setter omittedpublic RememberMeToken(){}public RememberMeToken(PersistentRememberMeToken token){this.series = token.getSeries();this.username = token.getUsername();this.tokenValue = token.getTokenValue();this.date = token.getDate();}}接下來(lái),使用Spring Data為實(shí)體添加一個(gè)存儲(chǔ)庫(kù):
public interface RememberMeTokenRepository extends MongoRepository<RememberMeToken, String>{RememberMeToken findBySeries(String series);List<RememberMeToken> findByUsername(String username); }然后,唯一相對(duì)繁重的編碼是為MongoDB實(shí)現(xiàn)PersistentTokenRepository:
public class MongoPersistentTokenRepositoryImpl implements PersistentTokenRepository {private final RememberMeTokenRepository rememberMeTokenRepository;public MongoPersistentTokenRepositoryImpl(RememberMeTokenRepository rememberMeTokenRepository){this.rememberMeTokenRepository = rememberMeTokenRepository;}@Overridepublic void createNewToken(PersistentRememberMeToken token) {RememberMeToken newToken = new RememberMeToken(token);this.rememberMeTokenRepository.save(newToken);}@Overridepublic void updateToken(String series, String tokenValue, Date lastUsed) {RememberMeToken token = this.rememberMeTokenRepository.findBySeries(series);if (token != null){token.setTokenValue(tokenValue);token.setDate(lastUsed);this.rememberMeTokenRepository.save(token);}}@Overridepublic PersistentRememberMeToken getTokenForSeries(String seriesId) {RememberMeToken token = this.rememberMeTokenRepository.findBySeries(seriesId);return new PersistentRememberMeToken(token.getUsername(), token.getSeries(), token.getTokenValue(), token.getDate());}@Overridepublic void removeUserTokens(String username) {List<RememberMeToken> tokens = this.rememberMeTokenRepository.findByUsername(username);this.rememberMeTokenRepository.delete(tokens);} }剩下的工作就是所有配置。 我需要在Java config類中將它們連接在一起:
@Configuration public class SocialAndSecurityConfig {@Injectprivate Environment environment;@Injectprivate AccountService accountService;@Injectprivate AuthenticationManager authenticationManager;@Injectprivate RememberMeTokenRepository rememberMeTokenRepository;...@Beanpublic RememberMeServices rememberMeServices(){PersistentTokenBasedRememberMeServices rememberMeServices = new PersistentTokenBasedRememberMeServices(environment.getProperty('application.key'), accountService, persistentTokenRepository());rememberMeServices.setAlwaysRemember(true);return rememberMeServices;}@Bean public RememberMeAuthenticationProvider rememberMeAuthenticationProvider(){RememberMeAuthenticationProvider rememberMeAuthenticationProvider = new RememberMeAuthenticationProvider(environment.getProperty('application.key'));return rememberMeAuthenticationProvider; }@Bean public PersistentTokenRepository persistentTokenRepository() {return new MongoPersistentTokenRepositoryImpl(rememberMeTokenRepository);} }最后一步是將“記住我”服務(wù)添加到安全性xml配置文件中,這是xml配置的最后一部分,我們現(xiàn)在無(wú)法消除它。 (更新:一個(gè)新項(xiàng)目Spring Security Java Config將用Spring Security中的Java config替換xml配置。)
<?xml version='1.0' encoding='UTF-8'?> <beans:beans xmlns='http://www.springframework.org/schema/security'xmlns:beans='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd'><http use-expressions='true' entry-point-ref='socialAuthenticationEntryPoint'><custom-filter position='PRE_AUTH_FILTER' ref='socialAuthenticationFilter' /><logout logout-url='/signout' delete-cookies='JSESSIONID' /><remember-me services-ref='rememberMeServices' /><!-- Configure these elements to secure URIs in your application --><intercept-url pattern='/favicon.ico' access='permitAll' /><intercept-url pattern='/robots.txt' access='permitAll' /><intercept-url pattern='/resources/**' access='permitAll' /><intercept-url pattern='/signin' access='permitAll'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/signin/*' access='permitAll'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/presentation/**' access='hasRole('ROLE_USER')'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/myAccount/**' access='hasRole('ROLE_USER')'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/myPost/**' access='hasRole('ROLE_AUTHOR')'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/admin/**' access='hasRole('ROLE_ADMIN')'requires-channel='#{environment['application.secureChannel']}' /><intercept-url pattern='/**' access='permitAll' /></http><authentication-manager alias='authenticationManager'><authentication-provider ref='socialAuthenticationProvider' /><authentication-provider ref='rememberMeAuthenticationProvider' /></authentication-manager></beans:beans> 這就是向我的博客應(yīng)用程序添加“記住我的身份驗(yàn)證”的全部方法。 現(xiàn)在,您可以通過(guò)Google / Facebook / Twitter登錄到我的網(wǎng)站,該網(wǎng)站將在接下來(lái)的兩周內(nèi)始終記住您。
參考:來(lái)自Jiwhiz博客的JCG合作伙伴 Yuan Ji 添加了Spring Security的RememberMe身份驗(yàn)證 。
翻譯自: https://www.javacodegeeks.com/2013/03/add-rememberme-authentication-with-spring-security.html
總結(jié)
以上是生活随笔為你收集整理的使用Spring Security添加RememberMe身份验证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 支持win7的虚拟光驱哪些比较好?还有哪
- 下一篇: 通过运行示例从WSO2 ESB开始