这篇文章开始,我们会进入Spring Security部分。大概会有三到四篇文章来介绍Security部分,在这篇文章中,我们会使用XML配置的方式来配置一个简单的Spring Security登录的例子,感受一下什么是Spring Security,我们怎么使用Spring Security。
1. 什么是Spring Security?
Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架。Spring Security提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权。什么叫Web请求级别和方法调用级别呢?就会当我们通过Controller发送一个请求或者我们的DispatcherSevlet接受到一个请求的时候,我们使用Spring Security 事先声明好的filter,来拦截所有的请求,判断用户是否有权访问该资源。所以,我们会在Spring Security中用到依赖注入和切面编程(AspectJ)的技术。
Spring Security借助一系列Servlet Filter来提供各种安全性功能。我们只需在web.xml配置一个Filter就可以了。DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的工作并不多。只是将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个<bean>注册在Spring应用的上下文中
2. 一个简单的Spring Security登录例子:
首先我们新建Maven项目,过程和前面文章相同,新建后的项目结构如下:
完善你的pom.xml中的依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SpringSecurity</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringSecurity Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- ... other dependency elements ... -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>SpringSecurity</finalName>
</build>
</project>
作为Spring项目,首先就要有一个DispatcherServlet对吧?配置你的DispatcherServlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="Hello" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
我们将Spring Security的配置均放在security.xml中:
<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-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http auto-config="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_USER')" />
<logout logout-url="/logout" logout-success-url="/logoutPage" invalidate-session="true"/>
<csrf disabled="true" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="yanming" password="123" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
我们来解释一下这段代码:
1.http auto-config:默认的策略进行访问控制,包括一个默认的访问登录界面(我们在这个项目中并没有提供登陆的界面,稍后会说到)
2.authentication-manager:认证管理器负责确定用户的身份,认证管理器由AuthenticationManager接口定义,这里我们就用了缓存的用户信息
3.intercept-url pattern :通过pattern指定当前intercept-url定义应当作用于哪些url。
4.logout:匹配我们退出登录的url 在我们的Spring Security4.x中,我们需要关闭csrf才能够使用/logout。
web.xml中配置filter以及servlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Spring MVC Application</display-name>
<!-- Spring MVC -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<!--Sources标注的文件夹下需要新建一个spring文件夹-->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/DispatcherServlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Loads Spring Security config file -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/security.xml
</param-value>
</context-param>
<!-- 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>
</web-app>
在Hello包中定义HelloController:
package Hello;
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;
/**
* Created by YanMing on 2017/3/15.
*/
@Controller
public class HelloController {
@RequestMapping(value = {"/" ,"/welcome"},method = RequestMethod.GET)
public ModelAndView homePage(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("title","Hello world");
modelAndView.setViewName("home");
return modelAndView;
}
@RequestMapping(value = {"/logoutPage"},method = RequestMethod.GET)
public ModelAndView logoutPage(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("logout");
return modelAndView;
}
@RequestMapping(value = "/admin",method = RequestMethod.GET)
public ModelAndView adminPage(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("title","Please log in");
modelAndView.setViewName("admin");
return modelAndView;
}
}
三个映射很简单,返回三个modelandview对象,匹配对应url同时返回相应的jsp文件。
在WEB-INF中定义jsp文件:
admin.jsp:
<%--
Created by IntelliJ IDEA.
User: YanMing
Date: 2017/3/14
Time: 21:31
To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<body>
<h1>Title:${title}</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>
home.jsp:
<%--
Created by IntelliJ IDEA.
User: YanMing
Date: 2017/3/15
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@page session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h1>Title:${title}</h1>
<a href="<c:url value="/admin" />" >Login</a></h2>
</body>
</html>
logout.jsp(对应退出成功以后的页面):
<%--
Created by IntelliJ IDEA.
User: YanMing
Date: 2017/3/15
Time: 15:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<h1>Logout Successfully!</h1>
</head>
<body>
</body>
</html>
配置Tomcat,不会配置的同学点击之前文章
然后在页面中输入localhost:8080
点击Login:
输入 yaming 123 登录
点击Logout
至此,一个简单的Spring Security的登录例子就写完了。在下一篇文章中,我们会开始使用数据库来存储我们的用户名密码。所以,我会重新使用Java 来配置Spring Security。不过,xml的配置过程显得很清晰,理解起来也很简单。同时下篇文章我也会详细的讲解Spring Security的核心部分以及具体过程。
P.S. 文章不妥之处还望指正