1.簡(jiǎn)介
本文將重點(diǎn)介紹使用 Spring Security
登錄。 本文將構(gòu)建在之前簡(jiǎn)單的 Spring MVC示例 之上,因?yàn)檫@是設(shè)置Web應(yīng)用程序和登錄機(jī)制的必不可少的。
2. Maven 依賴
要將Maven依賴項(xiàng)添加到項(xiàng)目中,請(qǐng)參閱Spring Security with Maven 一文。 標(biāo)準(zhǔn)的 spring-security-web 和 spring-security-config 都是必需的。
3. Spring Security Java配置
我們首先創(chuàng)建一個(gè)擴(kuò)展 WebSecurityConfigurerAdapter
的 Spring Security 配置類。 通過(guò)添加 @EnableWebSecurity ,我們獲得了Spring Security和MVC集成支持:
@Configuration @EnableWebSecurity public class SecSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user1").password(passwordEncoder().encode("user1Pass")).roles("USER") .and() .withUser("user2").password(passwordEncoder().encode("user2Pass")).roles("USER") .and() .withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN"); } @Override protected void configure(final HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() .antMatchers("/login*").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html", true) //.failureUrl("/login.html?error=true") .failureHandler(authenticationFailureHandler()) .and() .logout() .logoutUrl("/perform_logout") .deleteCookies("JSESSIONID") .logoutSuccessHandler(logoutSuccessHandler()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
在此示例中,我們使用內(nèi)存身份驗(yàn)證并定義了3個(gè)用戶。
現(xiàn)在來(lái)看看我們用來(lái)創(chuàng)建表單登錄配置的元素。
3.1. authorizeRequests()
我們?cè)试S匿名訪問(wèn)*/login*,以便用戶可以進(jìn)行身份驗(yàn)證,同時(shí)也是保護(hù)其他請(qǐng)求。請(qǐng)注意,*antMatchers()*元素的順序很重要 - 首先需要填寫具體的路徑規(guī)則,然后是才是大致匹配的規(guī)則。
3.2. formLogin()
這有幾種方法可以用來(lái)配置表單登錄的行為:
loginPage() – 自定義登錄頁(yè)面
loginProcessingUrl() – 提交username和password的URL
defaultSuccessUrl() – 登錄成功后跳轉(zhuǎn)的URL
failureUrl() – 登錄失敗后跳轉(zhuǎn)的URL
3.3. Authentication Manager
身份驗(yàn)證提供程序由一個(gè)簡(jiǎn)單的內(nèi)存實(shí)現(xiàn)支持 - InMemoryUserDetailsManager 。 當(dāng)尚不需要完整的持久性機(jī)制時(shí),這對(duì)于進(jìn)行快速原型設(shè)計(jì)很有用。
從Spring 5開(kāi)始,我們還必須定義密碼編碼器。 在我們的例子中,我們使用了 BCryptPasswordEncoder 。
4. 添加Spring Security到Web應(yīng)用
要使用上面定義的Spring Security配置,我們需要將其添加到Web應(yīng)用程序。 在這種情況下,我們不需要任何 web.xml :
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[] {SecSecurityConfig.class}; } }
注意,如果我們使用Spring Boot應(yīng)用程序,則不需要此初始化程序。 有關(guān)如何在Spring Boot中加載安全性配置的更多詳細(xì)信息,詳情參閱 Spring Boot security auto-configuration
5. Spring Security XML配置
我們來(lái)看看相應(yīng)的XML配置。整個(gè)項(xiàng)目使用Java配置,因此我們需要通過(guò)Java @Configuration 類導(dǎo)入XML配置文件:
@Configuration @ImportResource({ "classpath:webSecurityConfig.xml" }) public class SecSecurityConfig { public SecSecurityConfig() { super(); } }
以及Spring Security 的XML配置– webSecurityConfig.xml :
<http use-expressions="true"> <intercept-url pattern="/login*" access="isAnonymous()" /> <intercept-url pattern="/**" access="isAuthenticated()"/> <form-login login-page='/login.html' default-target-url="/homepage.html" authentication-failure-url="/login.html?error=true" /> <logout logout-success-url="/login.html" /> </http> <authentication-manager> <authentication-provider> <user-service> <user name="user1" password="user1Pass" authorities="ROLE_USER" /> </user-service> <password-encoder ref="encoder" /> </authentication-provider> </authentication-manager> <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> </beans:bean>
6. web.xml
在引入Spring 4之前,我們?cè)?jīng)在 web.xml 中配置Spring Security - 只有一個(gè)額外的過(guò)濾器添加到 Spring MVC 的web.xml中:
<display-name>Spring Secured Application</display-name> <!-- Spring MVC --> <!-- ... --> <!-- Spring Security --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
過(guò)濾器 - DelegatingFilterProxy - 簡(jiǎn)單地委托給一個(gè)Spring管理的bean - FilterChainProxy-它本身可以從完整的Spring bean生命周期管理中受益。
7. Login Form
登錄表單頁(yè)面使用簡(jiǎn)單的機(jī)制將視圖名稱映射到URL 向Spring MVC注冊(cè),且無(wú)需編寫Controller:
registry.addViewController("/login.html");
對(duì)應(yīng)于 login.jsp :
<html> <head></head> <body> <h1>Login</h1> <form name='f' action="login" method='POST'> <table> <tr> <td>User:</td> <td><input type='text' name='username' value=''></td> </tr> <tr> <td>Password:</td> <td><input type='password' name='password' /></td> </tr> <tr> <td><input name="submit" type="submit" value="submit" /></td> </tr> </table> </form> </body> </html>
Spring Login form包含以下相關(guān)組件:
login - 接受表單POST的URL,觸發(fā)身份驗(yàn)證過(guò)程
username - 用戶名
password - 密碼
8.進(jìn)一步配置Spring登錄
當(dāng)我們?cè)谏厦娼榻BSpring安全配置時(shí),我們簡(jiǎn)要討論了一些登錄機(jī)制的配置 - 現(xiàn)在詳細(xì)介紹一下。
覆蓋Spring Security中大多數(shù)默認(rèn)值的一個(gè)原因是隱藏應(yīng)用程序受Spring Security保護(hù)的事實(shí),并最大限度地減少潛在攻擊者對(duì)應(yīng)用程序的了解。
完全配置后,login元素如下所示:
@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .loginPage("/login.html") .loginProcessingUrl("/perform_login") .defaultSuccessUrl("/homepage.html",true) .failureUrl("/login.html?error=true") }
或者相應(yīng)的XML配置:
<form-login login-page='/login.html' login-processing-url="/perform_login" default-target-url="/homepage.html" authentication-failure-url="/login.html?error=true" always-use-default-target="true"/>
8.1. 登錄頁(yè)
接下來(lái),讓我們看看如何使用*loginPage()*方法配置自定義登錄頁(yè)面:
http.formLogin()
.loginPage("/login.html")
或者,使用XML配置:
login-page='/login.html'
如果我們不指定這個(gè),Spring Security將在*/login*上生成一個(gè)非常基本的登錄表單。
8.2. 登錄的POST URL
觸發(fā)身份驗(yàn)證默認(rèn)的URL是*/login*,我們可以使用 loginProcessingUrl 方法來(lái)覆蓋此URL:
http.formLogin() .loginProcessingUrl("/perform_login")
或者,使用XML配置:
login-processing-url="/perform_login"
覆蓋此默認(rèn)URL的一個(gè)很好的理由是:隱藏應(yīng)用程序受 Spring Security 保護(hù)的事實(shí) - 該信息不應(yīng)在外部提供。
8.3. 登錄成功頁(yè)面
成功登錄過(guò)程后,用戶將被重定向到頁(yè)面 - 默認(rèn)情況下,該頁(yè)面是Web應(yīng)用程序的根目錄。
我們可以通過(guò)*defaultSuccessUrl()*
方法覆蓋它:
http.formLogin() .defaultSuccessUrl("/homepage.html")
或者,使用XML配置:
default-target-url="/homepage.html"
如果 always-use-default-target
設(shè)置為 true ,則用戶始終會(huì)重定向到此頁(yè)面。 如果該屬性設(shè)置為 false ,則在提示進(jìn)行身份驗(yàn)證之前,用戶將被重定向到他們想要訪問(wèn)的上一頁(yè)。
8.4. 登錄失敗頁(yè)面
與登錄頁(yè)面相同,默認(rèn)情況下, Spring Security 會(huì)在*/login?error*
自動(dòng)生成登錄失敗頁(yè)面。
要覆蓋它,我們可以使用*failureUrl()*
方法:
http.formLogin() .failureUrl("/login.html?error=true")
或者XML:
authentication-failure-url="/login.html?error=true"
9. 結(jié)論
在這個(gè)Spring登錄示例中,我們配置了一個(gè)簡(jiǎn)單的身份驗(yàn)證過(guò)程 - 我們討論了Spring安全登錄表單,安全配置和一些可用的更高級(jí)的自定義。
這個(gè)Spring登錄教程的實(shí)現(xiàn)可以在GitHub 項(xiàng)目中找到 - 這是一個(gè)基于Eclipse的項(xiàng)目,所以它應(yīng)該很容易導(dǎo)入和運(yùn)行。
當(dāng)項(xiàng)目在本地運(yùn)行時(shí),可以在以下位置訪問(wèn)示例HTML:
http://localhost:8080/spring-security-mvc-login/login.html
總結(jié)
以上所述是小編給大家介紹的Spring Security 表單登錄功能的實(shí)現(xiàn)方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!