本文將重點介紹使用Spring Security
登陸。 本文將構建在以前簡單的Spring MVC示例之上,由於這是設置Web應用程序和登陸機制的必不可少的。html
要將Maven依賴項添加到項目中,請參閱Spring Security with Maven一文。 標準的spring-security-web
和spring-security-config
都是必需的。java
咱們首先建立一個擴展WebSecurityConfigurerAdapter
的Spring Security
配置類。 經過添加@EnableWebSecurity
,咱們得到了Spring Security和MVC集成支持:git
@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();
}
}
複製代碼
在此示例中,咱們使用內存身份驗證並定義了3個用戶。github
如今來看看咱們用來建立表單登陸配置的元素。web
咱們容許匿名訪問*/login*,以便用戶能夠進行身份驗證,同時也是保護其餘請求。請注意,*antMatchers()*元素的順序很重要 - 首先須要填寫具體的路徑規則,而後是纔是大體匹配的規則。spring
這有幾種方法能夠用來配置表單登陸的行爲:express
身份驗證提供程序由一個簡單的內存實現支持 - InMemoryUserDetailsManager。 當尚不須要完整的持久性機制時,這對於進行快速原型設計頗有用。spring-mvc
從Spring 5開始,咱們還必須定義密碼編碼器。 在咱們的例子中,咱們使用了BCryptPasswordEncoder。安全
要使用上面定義的Spring Security配置,咱們須要將其添加到Web應用程序。 在這種狀況下,咱們不須要任何web.xml:mvc
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SecSecurityConfig.class};
}
}
複製代碼
注意,若是咱們使用Spring Boot應用程序,則不須要此初始化程序。 有關如何在Spring Boot中加載安全性配置的更多詳細信息,詳情參閱Spring Boot security auto-configuration
咱們來看看相應的XML配置。整個項目使用Java配置,所以咱們須要經過Java @Configuration
類導入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>
複製代碼
在引入Spring 4以前,咱們曾經在web.xml
中配置Spring Security - 只有一個額外的過濾器添加到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>
複製代碼
過濾器 - DelegatingFilterProxy - 簡單地委託給一個Spring管理的bean - FilterChainProxy-它自己能夠從完整的Spring bean生命週期管理中受益。
登陸表單頁面使用簡單的機制將視圖名稱映射到URL向Spring MVC註冊,且無需編寫Controller:
registry.addViewController("/login.html");
複製代碼
對應於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安全配置時,咱們簡要討論了一些登陸機制的配置 - 如今詳細介紹一下。
覆蓋Spring Security中大多數默認值的一個緣由是隱藏應用程序受Spring Security保護的事實,並最大限度地減小潛在攻擊者對應用程序的瞭解。
徹底配置後,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")
}
複製代碼
或者相應的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"/>
複製代碼
接下來,讓咱們看看如何使用*loginPage()*方法配置自定義登陸頁面:
http.formLogin()
.loginPage("/login.html")
複製代碼
或者,使用XML配置:
login-page='/login.html'
複製代碼
若是咱們不指定這個,Spring Security將在*/login*上生成一個很是基本的登陸表單。
觸發身份驗證默認的URL是*/login*,咱們可使用loginProcessingUrl方法來覆蓋此URL:
http.formLogin()
.loginProcessingUrl("/perform_login")
複製代碼
或者,使用XML配置:
login-processing-url="/perform_login"
複製代碼
覆蓋此默認URL的一個很好的理由是:隱藏應用程序受Spring Security
保護的事實 - 該信息不該在外部提供。
成功登陸過程後,用戶將被重定向到頁面 - 默認狀況下,該頁面是Web應用程序的根目錄。
咱們能夠經過*defaultSuccessUrl()*方法覆蓋它:
http.formLogin()
.defaultSuccessUrl("/homepage.html")
複製代碼
或者,使用XML配置:
default-target-url="/homepage.html"
複製代碼
若是always-use-default-target設置爲true
,則用戶始終會重定向到此頁面。 若是該屬性設置爲false
,則在提示進行身份驗證以前,用戶將被重定向到他們想要訪問的上一頁。
與登陸頁面相同,默認狀況下,Spring Security
會在*/login?error*自動生成登陸失敗頁面。
要覆蓋它,咱們可使用*failureUrl()*方法:
http.formLogin()
.failureUrl("/login.html?error=true")
複製代碼
或者XML:
authentication-failure-url="/login.html?error=true"
複製代碼
在這個Spring登陸示例中,咱們配置了一個簡單的身份驗證過程 - 咱們討論了Spring安全登陸表單,安全配置和一些可用的更高級的自定義。
這個Spring登陸教程的實現能夠在GitHub項目中找到 - 這是一個基於Eclipse的項目,因此它應該很容易導入和運行。
當項目在本地運行時,能夠在如下位置訪問示例HTML:
http://localhost:8080/spring-security-mvc-login/login.html
複製代碼
做者:baeldung
譯者:Leesen