Spring Security入門程序註釋示例
在上一篇文章中,我們使用XML文件來配置 Spring Security 在Spring MVC中的環境。在本教程中,我們將來學習如何將基於XML的Spring Security項目轉換成純 Spring 註解項目。
注意:由於在這一系列教程中使用的是Maven來創建工程,如果不瞭解 Mave 如何使用的,可以參考:http://www.yiibai.com/maven/create-a-maven-web-project-with-eclipse.html
一些要用到的技術:
- Spring 3.2.8.RELEASE
- Spring Security 3.2.3.RELEASE
- Eclipse 4.2
- JDK 1.6
- Maven 3
- Tomcat 7 (Servlet 3.x)
一些需要注意的事項:
本教程使用 WebApplicationInitializer 來自動加載 Spring 上下文加載器,這些僅在 Servlet 3.X 容器中支持,例如:Tomcat7和 Jetty8。
由於我們使用了WebApplicationInitializer,所以不需要web.xml配置文件。
Spring Security註釋在舊版本的Servlet容器2.x中支持,例如:Tomcat6. 如果您使用經典的XML文件來加載Spring上下文,本教程仍然能夠部署在Servlet容器2.X 中,例如,Tomcat6。
2. 目錄結構
下面我們來看看本教程最終的目錄結構,如下圖中所示:
3. Spring Security依懶
要使用Spring security, 我們需要 spring-security-web 和 spring-security-config.
pom.xml
<dependencies>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!-- jstl for jsp page -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
</dependencies>
4. Spring MVC Web應用程序
一些簡單的控制器,如下所示:
- 如果 URL = /welcome 或 / , 返回 hello 頁面;
- 如果 URL = /admin , 返回 admin 頁面;
- 如果 URL = /dba , 返回admin 頁面;
接下來,我們將保證 /admin 和 /dba URLs.
HelloController.java
package com.yiibai.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class HelloController {
@RequestMapping(value = { "/", "/welcome\*\*" }, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is welcome page!");
model.setViewName("hello");
return model;
}
@RequestMapping(value = "/admin\*\*", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page - Admin Page!");
model.setViewName("admin");
return model;
}
@RequestMapping(value = "/dba\*\*", method = RequestMethod.GET)
public ModelAndView dbaPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page - Database Page!");
model.setViewName("admin");
return model;
}
}
兩個 JSP 頁面如下所示:
hello.jsp
<%@page session="false"%>
Title : ${title}
Message : ${message}
admin.jsp
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
Title : ${title}
Message : ${message}
<c:if test="${pageContext.request.userPrincipal.name != null}">
<h2>Welcome : ${pageContext.request.userPrincipal.name}
| <a href="<c:url value="/logout" />" > Logout</a></h2>
</c:if>
5. Spring Security配置
5.1創建 Spring Security 配置文件,並 @EnableWebSecurity 註解,如下代碼所示:
SecurityConfig.java
package com.yiibai.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("yiibai").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/\*\*").access("hasRole('ROLE\_ADMIN')")
.antMatchers("/dba/\*\*").access("hasRole('ROLE\_ADMIN') or hasRole('ROLE\_DBA')")
.and().formLogin();
}
}
這等同於以下 Spring Security xml 文件:
<authentication-manager>
<authentication-provider>
<user-service>
<user name="yiibai" password="123456" authorities="ROLE\_USER" />
<user name="admin" password="123456" authorities="ROLE\_ADMIN" />
<user name="dba" password="123456" authorities="ROLE\_DBA" />
</user-service>
</authentication-provider>
</authentication-manager>
5.2 創建一個擴展 AbstractSecurityWebApplicationInitializer 的一個類, 它將會自動地加載 springSecurityFilterChain 。
SpringSecurityInitializer.java
package com.yiibai.config.core;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
//do nothing
}
這等同於以下 Spring Security 中的 web.xml 文件,如下:
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/\*</url-pattern>
</filter-mapping>
6. Spring MVC配置
6.1 這是一個配置類, 定義視圖技術和導入上述 SecurityConfig.java.
AppConfig.java
package com.yiibai.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.yiibai.web.*" })
@Import({ SecurityConfig.class })
public class AppConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
這將等同於以下 Spring XML文件:
<context:component-scan base-package="com.yiibai.web.*" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
6.2 創建一個 Initializer 類來加載所有的一切,如下代碼:
SpringMvcInitializer.java
package com.yiibai.config.core;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.yiibai.config.AppConfig;
public class SpringMvcInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>\[\] getRootConfigClasses() {
return new Class\[\] { AppConfig.class };
}
@Override
protected Class<?>\[\] getServletConfigClasses() {
return null;
}
@Override
protected String\[\] getServletMappings() {
return new String\[\] { "/" };
}
}
到這裏,實例介紹完成了,您可以參考本實例並自己親自動實踐一下體驗。
注意事項:
在Servlet 3.X容器環境+ Spring容器中將會自動檢測並加載初始化類。
7. 示例
7.1. 打開進入歡迎頁面 – http://localhost:8080/spsecurity-helloworld-annotation/welcome 如下圖所示 -
7.2 嘗試訪問 http://localhost:8080/spsecurity-helloworld-annotation/admin 頁面,Spring Security將截取請求並重定向到 /login,並顯示一個默認的登錄表單。
7.3. 如果用戶名和密碼不正確,將提示(顯示)錯誤信息,並且Spring將重定向到網址:http://localhost:8080/spsecurity-helloworld-annotation/login?error.
7.4. 如果用戶名和密碼是正確的,Spring將請求重定向到原來請求的URL並顯示該網頁。
7.5.對於未經授權的用戶,Spring會顯示403拒絕訪問頁面。例如,用戶名 「yiibai」 或 「dba」 嘗試訪問 /admin 這個網址。可以看到一個禁止訪問的提示 -
下載源代碼
下載本實例的源代碼 – spsecurity-helloworld-annotation.zip (12 KB)
參考
- Spring Security
- Spring Security Java Config Preview: Web Security
- Hello Spring MVC Security Java Config
- Wikipedia : Java Servlet
- Wikipedia : Apache Tomcat
- Spring Security Hello World XML實例