Spring Security - XML 配置


内容

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

基础知识

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

认证与授权

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

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

入门(实用指南)

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

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

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

简单的 Maven 项目 项目结构

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

XML 配置演示

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

  • Spring Web MVC
  • Spring-Security-Web
  • Spring-Security-核心
  • Spring 安全配置
  • 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”。虽然所有人都可以访问索引页面,但我们将保护我们的“管理”页面。

既然我们已经创建了路线,那么我们也可以添加页面。

在 /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>

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

配置。

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

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

继续我们创建最后一个配置文件——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 视图。

运行应用程序

通过这个简单的配置,我们的应用程序就可以使用了。我们可以右键单击该项目并选择 Run on Server。我们可以选择我们的 Tomcat 服务器。当服务器启动时,我们可以访问 localhost:8080/xmlconfigurationdemo 与我们的应用程序进行交互。

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

管理员您好