Spring Security入门程序注释示例

广告位

在上一篇文章中,我们使用XML文件来配置SpringSecurity在SpringMVC中的环境。在本教程中,…

在上一篇文章中,我们使用XML文件来配置SpringSecurity在SpringMVC中的环境。在本教程中,我们将来学习如何将基于XML的SpringSecurity项目转换成纯Spring注解项目。
注意:由于在这一系列教程中使用的是Maven来创建工程,如果不了解 Mave 如何使用的,可以参考:

一些要用到的技术:

  1. Spring 3.2.8.RELEASE
  2. Spring Security 3.2.3.RELEASE
  3. Eclipse 4.2
  4. JDK 1.6
  5. Maven 3
  6. Tomcat 7 (Servlet 3.x)

一些需要注意的事项:

  1. 本教程使用WebApplicationInitializer来自动加载Spring上下文加载器,这些仅在Servlet3.X容器中支持,例如:Tomcat7和Jetty8。
  2. 由于我们使用了WebApplicationInitializer,所以不需要web.xml配置文件。
  3. SpringSecurity注释在旧版本的Servlet容器2.x中支持,例如:Tomcat6.如果您使用经典的XML文件来加载Spring上下文,本教程仍然能够部署在Servlet容器2.X中,例如,Tomcat6。

2. 目录结构

下面我们来看看本教程最终的目录结构,如下图中所示: Spring Security入门程序注释示例

3. Spring Security依懒

要使用Spring security, 我们需要spring-security-web和spring-security-config.

pom.xml
<properties>  		<jdk.version>1.6</jdk.version>  		<spring.version>3.2.8.RELEASE</spring.version>  		<spring.security.version>3.2.3.RELEASE</spring.security.version>  		<jstl.version>1.2</jstl.version>  	</properties>    	<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应用程序

一些简单的控制器,如下所示:

  1. 如果 URL =/welcome或/, 返回 hello 页面;
  2. 如果 URL =/admin,返回admin页面;
  3. 如果URL =/dba, 返回admin页面;

接下来,我们将保证/admin和/dbaURLs.

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"%>  <html>  <body>  	<h1>Title : ${title}</h1>	  	<h1>Message : ${message}</h1>	  </body>  </html>
admin.jsp
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  <%@page session="true"%>  <html>  <body>  	<h1>Title : ${title}</h1>  	<h1>Message : ${message}</h1>    	<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>  </body>  </html>

5. Spring Security配置

5.1创建 SpringSecurity 配置文件,并@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 文件:

<http auto-config="true">  		<intercept-url pattern="/admin**" access="ROLE_ADMIN" />  		<intercept-url pattern="/dba**" access="ROLE_ADMIN,ROLE_DBA" />  	</http>    	<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>  		<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>

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[] { "/" };  	}  	  }

到这里,实例介绍完成了,您可以参考本实例并自己亲自动实践一下体验。

注意事项:

在Servlet3.X容器环境+Spring容器中将会自动检测并加载初始化类。

7. 示例

7.1. 打开进入欢迎页面 – http://localhost:8080/spsecurity-helloworld-annotation/welcome 如下图所示 – Spring Security入门程序注释示例

7.2尝试访问http://localhost:8080/spsecurity-helloworld-annotation/admin页面,SpringSecurity将截取请求并重定向到/login,并显示一个默认的登录表单。 Spring Security入门程序注释示例

7.3.如果用户名和密码不正确,将提示(显示)错误信息,并且Spring将重定向到网址:http://localhost:8080/spsecurity-helloworld-annotation/login?error. Spring Security入门程序注释示例

7.4.如果用户名和密码是正确的,Spring将请求重定向到原来请求的URL并显示该网页。 Spring Security入门程序注释示例

7.5.对于未经授权的用户,Spring会显示403拒绝访问页面。例如,用户名“yiibai”或“dba”尝试访问/admin这个网址。可以看到一个禁止访问的提示 –

下载源代码

下载本实例的源代码 –(12 KB)

参考

贺, 贺朝

关于作者: 贺朝

为您推荐