Spring Security - XML 配置

内容

  • 基础知识
  • 入门(实用指南)

基础知识

在本文中,我们将讨论如何使用 XML 配置来配置 Spring Security。 我们将使用 Spring Security 开发一个简单的 Spring 应用程序。 在这样做的同时,我们将详细讨论我们正在使用的每个组件。

认证和授权

  • Authentication − 认证,身份验证确保用户或客户是他们声称的身份。 Spring Security 使我们能够通过多种方式执行身份验证。 Spring Security 支持基本认证、LDAP 认证、JDBC 认证等。
  • Authorization − 授权,确保用户是否有权执行该操作。 如果我们的应用程序是一个复杂的应用程序,具有不同类型的用户,例如管理员、普通用户和其他权限较低的用户,我们需要在应用程序中维护访问控制。例如,来宾用户不应该能够访问管理内容。 因此,为了控制对应用程序中各种资源的访问,我们需要检查用户是否有权访问该资源。

以上主题是 Spring Security 的两个主要组成部分。 Spring Security 为我们提供了各种内置功能来在我们的应用程序中实现身份验证和授权。 我们可以将这些功能与我们的更改一起使用,以非常快速地保护应用程序。除此之外,Spring Security 还允许对前面提到的功能进行大量自定义,以实现我们自己的复杂身份验证和授权。

入门(实用指南)

让我们看一个使用内置 Spring Security 功能的基本示例。 在这个例子中,我们将使用 Spring security 提供的开箱即用选项来保护我们的应用程序。这将使我们了解 Spring Security 的各种组件以及我们如何将它们用于我们的应用程序。 我们将使用 XML 来配置我们应用程序的安全功能。

我们将用于我们的应用程序的工具将是 Spring Tool Suite 4 和 Apache Tomcat 服务器 9.0。 它们都可以免费下载和使用。

首先,让我们在 STS 中启动一个新的简单 Maven 项目。 我们可以根据自己的选择选择组 ID、工件 ID。 之后,我们点击完成。 结果,我们已将项目添加到工作区。 让我们给 STS 一些时间来构建和验证我们的项目。

简单的 Maven 项目 Project 项目结构

我们的项目结构最终看起来与此类似。

XML 配置演示

接下来,让我们添加依赖项。 我们将选择以下依赖项。

  • Spring Web MVC
  • Spring-Security-Web
  • Spring-Security-Core
  • Spring-Security-Config
  • Javax Servlet API

pom.xml

添加这些依赖项后,我们就可以配置我们的项目了。 让我们看一下我们的 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 
   https://maven.apache.org/xsd/maven-4.0.0.xsd> 
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorial.spring.security</groupId> 
      <artifactId>xmlconfigurationdemo</artifactId> 
      <version>0.0.1-SNAPSHOT</version> 
      <packaging>war</packaging> 
      <name>Spring Security with XML configuration</name> <description>Spring Security with XML configuration</description> 
      <properties> 
      <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> 
      <dependencies> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-webmvc</artifactId> 
         <version>5.0.2.RELEASE<version> 
         </dependency> <dependency> 
         <groupId>org.springframework.security</groupId> 
         <artifactId>spring-security-web</artifactId> 
         <version>5.0.0.RELEASE</version> 
      </dependency>
      <dependency> 
         <groupId>org.springframework.security</groupId> 
         <artifactId>spring-security-core</artifactId> 
         <version>5.0.0.RELEASE</version> 
      </dependency> 
      <dependency> 
         <groupId>org.springframework.security</groupId> 
         <artifactId>spring-security-config</artifactId> 
         <version>5.0.0.RELEASE</version> 
      </dependency> 
      <dependency> 
         <groupId>javax.servlet</groupId> 
         <artifactId>javax.servlet-api</artifactId> 
         <version>3.1.0</version> 
         <scope>provided</scope> 
      </dependency> 
      </dependencies> 
      <build> 
         <plugins> 
            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version> 
            <configuration>
               <failOnMissingWebXml>false</failOnMissingWebXml> 
            </configuration> 
         </plugin> 
      </plugins> 
   </build> 
</project>

控制器和视图

首先,我们将创建我们的控制器。 因此,让我们创建一个名为 controller 的包并将我们的 HomeController 类添加到包中。

实例


package com.tutorial.spring.security.xmlconfigurationdemo.controller; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
@Controller public class HomeController { @GetMapping("/")
public String index() { return "index"; } 
@GetMapping("/admin") 
public String admin() { return "admin"; } }

在这里,我们有两个端点 - "index"和"admin"。 尽管所有人都可以访问索引页面,但将保护我们的"admin"管理页面。

既然,我们已经创建了路由,让我们也添加页面。

在我们的 /src/main/webapp 文件夹中,让我们创建一个名为 WEB-INF 的文件夹。 然后在其中,我们将创建一个名为 views 的文件夹,我们将在其中创建我们的视图。

让我们创建我们的第一个视图 −

实例


<%@ page language="java" contentType="text/html; 
charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<!DOCTYPE html> 
<html> 
   <head> 
      <meta charset="ISO-8859-1"> <title>Insert title here</title> 
   </head> 
   <body> 
      <h2>Welcome to Spring Security!</h2>
   </body> 
</html>

然后我们创建我们的管理视图。

实例


<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<DOCTYPE html> 
<html> 
   <head> 
      <meta charset="ISO-8859-1"> <title>Insert title here</title> 
   </head> 
   <body> 
      Hello Admin 
   </body> 
</html>

继续,让我们配置我们的应用程序。

配置。

web.xml

现在,让我们添加我们的第一个 xml 文件——web.xml 文件。

实例


<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE xml> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
   http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> 
   <servlet-name>spring</servlet-name> 
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
   <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/app-config.xml</param-value> 
   </init-param> 
   <load-on-startup>1</load-on-startup> 
   </servlet> 
   <servlet-mapping> 
   <servlet-name>spring</servlet-name> 
   <url-pattern>/</url-pattern> 
   </servlet-mapping> 
   <listener> 
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener> 
   <context-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value> /WEB-INF/security-config.xml </param-value> 
   </context-param> 
   <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>

代码分解

  • Dispatcher Servlet − 我们在这里声明的第一个 servlet 是 Dispatcher servlet。 dispatcher servlet 是任何 Spring MVC 应用程序的入口点,是整个 Spring MVC 框架设计的核心。它拦截所有 HTTP 请求并将它们分派给已注册的处理程序以处理 Web 请求。 它还提供了方便的映射和异常处理工具。加载 servlet 的顺序取决于"load-on-startup"值。 "load-on-startup"值较低的 Servlet 先于值较高的 Servlet 加载。
  • contextConfigLocation − 它是一个字符串,指示可以找到上下文的位置。 此字符串表示可以加载我们的配置的文件的路径。
  • servlet-mapping − 我们使用 Servlet Mapping 来告诉 Spring Container 哪个请求路由到哪个 servlet。 在我们的例子中,我们将所有请求路由到我们的"spring" Dispatcher servlet。
  • listener − 侦听某些类型的事件并在该事件发生时触发适当功能的类。 每个侦听器都绑定到一个事件。在我们的例子中,我们将使用 ContextLoaderListener 为 Web 应用程序创建一个根 Web 应用程序上下文。 然后将其放入可用于加载和卸载 spring 管理的 bean 的 ServletContext 中。
  • filter − Spring 使用过滤器在将请求交给 Dispatcher Servlet 之前对其进行处理,并且还用于在它们被调度后处理响应。 DelegatingFilterProxy 将应用程序上下文链接到 web.xml 文件。到达此应用程序的请求将在到达其控制器之前通过我们命名为 "spring SecurityFilterChain" 的过滤器。这是 Spring Security 可以在将请求传递给下一组过滤器或处理程序之前接管请求并对其执行操作的地方。

security-config.xml

接下来我们将创建我们的 security-config.xml 文件。

实例


<?xml version="1.0" encoding="UTF-8"?> 
<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.xsd 
http://www.springframework.org/schema/security 
http://www.springframework.org/schema/security/spring-security.xsd"> 
<http auto-config="true"> 
<intercept-url pattern="/admin"
access="hasRole('ROLE_ADMIN')" /> </http> 
<authentication-manager> 
<authentication-provider> 
   <user-service> 
   <user name="admin" password="{noop}1234" authorities="ROLE_ADMIN" /> 
   </user-service> 
   </authentication-provider> </authentication-manager> 
   <beans:bean id ="passwordEncoder" 
      class = "org.springframework.security.crypto.password.NoOpPasswordEncoder" 
      factory-method = "getInstance">
   </beans:bean> 
</beans:beans>

代码分解

  • http element − 所有与 Web 相关的命名空间功能的父级。 在这里,我们可以配置拦截哪些 URL,需要哪些权限,使用哪种登录类型,以及所有这些配置。
  • auto-config − 将此属性设置为 true 会自动设置表单登录、基本登录和注销功能。 Spring Security 通过使用标准值和启用的特性来生成它们。
  • intercept-url − 它使用 access 属性设置我们想要保护的 URL 的模式。
  • access − 它指定允许哪些用户访问由模式属性指定的 URL。 它是根据用户的角色和权限完成的。 我们可以使用带有此属性的 SPEL。
  • authentication-manager − <authentication-manager> 用于在应用程序中配置用户、他们的密码和角色。 如果这些用户具有适当的角色,他们将可以访问应用程序的受保护部分。<authentication-provider< 将创建一个 DaoAuthenticationProvider bean,而 <user-service< 元素将创建一个 InMemoryDaoImpl。 所有 authentication-provider 元素将允许通过向身份验证管理器提供用户信息来对用户进行身份验证。
  • password-encoder − 这将注册一个密码编码器 bean。 为了简单起见,我们使用了 NoOpPasswordEncoder。

继续我们创建最后一个配置文件 – app-config 文件。 在这里,我们将添加我们的视图解析器代码并定义我们的基础包。

app-config.xml

实例


<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:mvc="http://www.springframework.org/schema/mvc" 
   xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" 
   http://www.springframework.org/schema/mvc 
   http://www.springframework.org/schema/mvc/spring-mvc.xsd 
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd 
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context.xsd"> 
   <mvc:annotation-driven /> 
   <context:component-scan
      base-package="com.tutorial.spring.security.xmlconfigurationdemo.controller"> 
   </context:component-scan> 
   <context:annotation-config>
   </context:annotation-config> 
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
      <property name="prefix" value="/WEB-INF/views/"></property> 
      <property name="suffix" value=".jsp"></property> 
   </bean> 
</beans>

在这里,我们可以看到我们正在注册我们之前创建的视图。 为此,我们使用 InternalResourceViewResolver 类,它将提供的 URI 映射到实际的 URI。

例如,使用上面的配置,如果我们请求 URI "/admin",DispatcherServlet 会将请求转发到

前缀 + 视图名称 + 后缀 = /WEB-INF/views/admin.jsp 视图。

运行应用程序

有了这个简单的配置,我们就可以准备好我们的应用程序了。我们可以右键单击该项目并选择在服务器上运行。 我们可以选择自己的 Tomcat 服务器。当服务器启动时,我们可以去 localhost:8080/xmlconfigurationdemo 与我们的应用程序进行交互。

如果我们输入正确的凭据,我们将能够登录并查看我们想要的内容。

Hello Admin