初识 Spring Security

前言

对于实际中的的项目而言,安全性是不得不考虑的问题。比如在一开始学习 Servlet 时,我们用来练手的许多 Web 项目,它的任意资源都是可以无需登录直接通过 URL 进行访问的,这意味着,任何人都可以访问你的任何路径。这是一件非常可怕的事情,让人感到非常不安全。

所以,认证和授权是我们不得不考虑的问题。所谓认证,就是谁可以登录进这个系统,比如你登录 QQ 总得需要一个账号吧。所谓授权,就是这个用户有哪些权限,可以做什么,不可以做什么,比如你作为普通用户在逛淘宝的时候想要删除某个违规的商品也是有心无力吧。

Spring Security 介绍

Spring Security 是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级分别处理身份认证和授权。

认证和授权的概念是通用的,不是 Spring Security 特有的。

Spring Security 的简单使用

1. 导入 Spring Security 的 Maven 依赖
<dependencies>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-web</artifactId>
		<version>5.0.1.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>
		<version>5.0.1.RELEASE</version>
	</dependency>
</dependencies>
2. 创建 Spring Security 配置文件

我们需要为 Spring Security 专门建立一个 Spring 的配置文件,该文件就用来作为 Spring Security 的配置。使用 Spring Security 我们还需要引入 Spring Security 的 NameSpace。内容如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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">

</beans>

Spring Security 命名空间的引入可以大大简化我们的开发步骤,它涵盖了大部分 Spring Security 常用的功能。

引入 Spring Security 的命名空间之后,我们需要进行具体的配置。要想保证一个系统的安全性,那么首先我们就要想到增加一个认证的环节。而要想使用 Spring Security 的认证,我们需要借助 http 元素。它是用于定义 Web 相关权限控制的。内容如下所示:

<security:http auto-config="true">
	<security:intercept-url pattern="/**" access="ROLE_USER"/>
</security:http>

在上面的代码的定义中,intercept-url 定义了权限控制的规则:其中,pattern 属性代表着哪些访问路径将被拦截(或者说是权限控制),这里的 “/**” 表示的是所有的路径都要被拦截;access 属性代表的是在请求 pattern 指定的 url 的时候需要拥有什么样的角色,如果拥有多个角色需要逗号分开, 这里的 “ROLE_USER” 表示请求的用户应当具有 ROLEUSER 角色,其中 “ROLE” 前缀是一个提示 Spring 使用基于角色的检查的标记。

在定义完权限控制的规则之后,我们还需要实现认证操作,可以借助 authentication-manager 元素来完成。内容如下所示:

<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="user" password="{noop}user"
                           authorities="ROLE_USER" />
            <security:user name="admin" password="{noop}admin"
                           authorities="ROLE_ADMIN" />
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

在上面的代码中, authentication-manager 指定了一个 AuthenticationManager(它用于处理来自于框架其他部分的认证请求)。其需要一个 AuthenticationProvider (对应 authentication-provider 元素)来进行真正的认证,默认情况下 authentication-provider 对应一个 DaoAuthenticationProvider,其需要 UserDetailsService(对应 user-service 元素)来获取用户信息 UserDetails(对应 user 元素)。

在这里简单的定义了 user 和 admin 的两个用户主要是为了用于学习使用,值得注意的是用户密码需要加上前缀 “{noop}”,这是为了告诉 Spring Security 要进行加密传输。在实际的项目中,用户名、密码、和权限信息肯定是要存储在数据库中的。

至此,Spring Security 的配置文件就简单配置完成了。完整配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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">

    <security:http auto-config="true" use-expressions="false">
        <!-- 配置资料连接,表示任意路径都需要ROLE_USER权限 -->
        <security:intercept-url pattern="/**" access="ROLE_USER" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="{noop}user"
                               authorities="ROLE_USER" />
                <security:user name="admin" password="{noop}admin"
                               authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>
3. 加载 Spring Security 配置文件

Spring Security 配置文件配置完毕之后,为了使之生效,我们需要告诉服务器在启动的时候加载配置文件。有两种方法可以实现上述目的:一是在 web.xml 中进行配置,二是在 Spring 的初始配置文件中引入它。通常我们选择在 web.xml 中配置它。

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring-security.xml</param-value>
</context-param>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

配置文件是可以通过 ContextLoaderListener 来加载和初始化的,上述代码中的 spring-security.xml 文件就是对应的 Spring Security 的配置文件。

接下来我们还需要在 web.xml 中定义一个 filter 用来拦截需要交给 Spring Security 处理的请求。需要注意的是:该 filter 一定要尽量定义在其它如 SpringMVC 等拦截请求之前。这里我们将拦截所有的请求,具体配置如下所示:

<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>
4. 运行项目

接下来可以 install 整个工程,然后启动 Tomcat,然后在浏览器中访问主页。会看到如下页面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TJ5itlOD-1588169892878)(img/01_01.png)]

因为上面在 Spring Security 的配置文件中配置好了所有的请求都需要 “ROLE_USER” 权限,所以当我们在请求主页的时候,Spring Security 发现我们还没有登录,Spring 会引导我们到由它自动为我们提供的登录界面。使用正确的用户名和密码(如上面配置的 user/user 或 admin/admin)登录后,如果符合对应的权限我们就可以访问主页了,否则将出现 403(禁止访问)界面。

思考

  1. 系统默认提供的登录页面这么丑,我们可以使用自己定义的登录页面吗?

    答: 可以的,这将会在后面的博客中进行讲解。除了可以自定义登录界面之外,还可以自定义登录失败界面等。

  2. 系统默认提供的登录页面是怎么来的呢?它怎么知道我有没有自己定义了登录页面呢?

    答: 当我们在 Spring Security 的配置文件中配置了 http 的 auto-config=“true” 时,Spring Security 将自动为我们生成登录页面。它等同于如下代码:

    <security:http>
    	<security:form-login/>
    	<security:http-basic/>
    	<security:logout/>
    </security:http>
    

    这些元素负责建立表单登录、基本的认证和登出处理。可以通过指定对应的属性来改变系统的默认行为,比如通过指定 form-login 就可以实现使用自定义的登录页面。

  3. 还有其它可以提供认证和授权的安全框架吗?

    答: 当然有,需要你自己去了解。

参考资料:W3Cschool _Spring Security。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值