首页 > SpringSecurit
头像
社交牛逼一号
编辑于 2021-09-02 23:21
+ 关注

SpringSecurit


概述:

在web应用开发中,安全无疑是十分重要的,选择Spring Security来保护web应用是一个非常好的选择。Spring Security 是Spring项目之中的一个安全模块,可以非常方便与Spring项目无缝集成。利用 Spring IoC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。特别是SpringBoot项目中加入Spring Security更是十分简单。

核心功能:

认证:用户登录,系统授权访问

授权:当前用户有哪些资源可以访问

攻击防护:防止伪造身份

核心就是一组过滤链,项目启动后会将自动配置。最核心的就是Basic Authentication Filter用来认证用户身份,一个soring security中一种过滤器处理一种认证方式。

spring security是spring采用AOP思想,基于servlet过滤器实现的安全框架,它提供了完善的认证机制和方法级别的授权功能。

快速入门

创建web项目

导入spring相关依赖

<dependencies>  <dependency>  <groupId>org.springframework.security</groupId>  <artifactId>spring-security-config</artifactId>  <version>5.1.5.RELEASE</version>  </dependency>  <dependency>  <groupId>org.springframework.security</groupId>  <artifactId>spring-security-taglibs</artifactId>  <version>5.1.5.RELEASE</version>  </dependency>  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-jdbc</artifactId>  <version>5.1.6.RELEASE</version>  </dependency>  <dependency>  <groupId>org.slf4j</groupId>  <artifactId>slf4j-log4j12</artifactId>  <version>1.7.26</version>  </dependency>  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-webmvc</artifactId>  <version>5.1.6.RELEASE</version>  </dependency>  <dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  <version>5.1.47</version>  </dependency>  <dependency>  <groupId>org.mybatis</groupId>  <artifactId>mybatis</artifactId>  <version>3.5.1</version>  </dependency>  <dependency>  <groupId>org.mybatis</groupId>  <artifactId>mybatis-spring</artifactId>  <version>2.0.1</version>  </dependency>  <dependency>  <groupId>javax.servlet</groupId>  <artifactId>javax.servlet-api</artifactId>  <version>4.0.1</version>  <scope>provided</scope>  </dependency>  <dependency>  <groupId>javax.servlet</groupId>  <artifactId>jsp-api</artifactId>  <version>2.0</version>  <scope>provided</scope>  </dependency>  <dependency>  <groupId>jstl</groupId>  <artifactId>jstl</artifactId>  <version>1.2</version>  </dependency>  <dependency>  <groupId>org.projectlombok</groupId>  <artifactId>lombok</artifactId>  <version>1.18.8</version>  </dependency>  <dependency>  <groupId>javax.annotation</groupId>  <artifactId>jsr250-api</artifactId>  <version>1.0</version>  </dependency>  </dependencies>

创建配置文件

spring的

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="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">  </beans>

springmvc的:

<?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:context="http://www.springframework.org/schema/context"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">   <!-- 配置扫描路径-->  <context:component-scan base-package="com.bruce.controller" use-default-filters="false">    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  </context:component-scan>    <mvc:default-servlet-handler/>   <mvc:annotation-driven/>  </beans>

use-default-filters="true" 的意思是自动扫描@controller @Repository @service 配置为flase就是只扫描指定的类!

web.xml

<!DOCTYPE web-app PUBLIC  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  "http://java.sun.com/dtd/web-app_2_3.dtd" >  <web-app>  <display-name>Archetype Created Web Application</display-name>   <!-- 初始化spring容器 -->  <context-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath:applicationContext.xml</param-value>  </context-param>  <listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>   <!-- post乱码过滤器 -->  <filter>  <filter-name>CharacterEncodingFilter</filter-name>  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  <init-param>  <param-name>encoding</param-name>  <param-value>utf-8</param-value>  </init-param>  </filter>  <filter-mapping>  <filter-name>CharacterEncodingFilter</filter-name>  <url-pattern>/*</url-pattern>  </filter-mapping>    <!-- 前端控制器 -->  <servlet>  <servlet-name>dispatcherServletb</servlet-name>  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->  <init-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath:springmvc.xml</param-value>  </init-param>  <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>  <servlet-name>dispatcherServletb</servlet-name>  <!-- 拦截所有请求jsp除外 -->  <url-pattern>/</url-pattern>  </servlet-mapping>  </web-app> 

springsecurity整合

导入config taglibs 依赖

spring-security-core.jar:核心包,任何SpringSecurity功能都需要此包 spring-security-web.jar:web工程必须,包含过滤器和相关的web安全基础结构代码 spring-security-config.jar:用于解析xml配置文件,用到SpringSecurity的xml配置文件的就要用到此包 spring-security-taglibs.jar:SpringSecurity提供的动态标签库,jsp页面可以用

<dependency>  <groupId>org.springframework.security</groupId>  <artifactId>spring-security-config</artifactId>  <version>5.1.5.RELEASE</version> </dependency>  <dependency>  <groupId>org.springframework.security</groupId>  <artifactId>spring-security-taglibs</artifactId>  <version>5.1.5.RELEASE</version> </dependency>

在web.xml中配置过滤器

<!-- 配置过滤器链 springSecurityFilterChain名称固定--> <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>

SpringSecurity 配置文件 spring-security.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"  xmlns:context="http://www.springframework.org/schema/context"  xmlns:p="http://www.springframework.org/schema/p"  xmlns:aop="http://www.springframework.org/schema/aop"  xmlns:tx="http://www.springframework.org/schema/tx"  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-4.2.xsd  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd  http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd">   <!--  设置可以用spring的el表达式配置Spring Security并自动生成对应配置组件(过滤器)  auto-config="true" 表示自动加载SpringSecurity的配置文件  use-expressions="true" 使用Spring的EL表达式  -->  <security:http auto-config="true" use-expressions="true">  <!--  拦截资源  pattern="/**" 拦截所有的资源  access="hasAnyRole('role1')" 表示只有role1这个角色可以访问资源  -->  <!--使用spring的el表达式来指定项目所有资源访问都必须有ROLE_USER或ROLE_ADMIN角色-->  <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"></security:intercept-url>  </security:http>   <!-- 设置置Spring Security认证用户来源 noop:SpringSecurity中默认 密码验证是要加密的 noop表示不加密 -->  <security:authentication-manager>  <security:authentication-provider>  <security:user-service>  <security:user name="shuaige" password="{noop}123" authorities="ROLE_USER"></security:user>  <security:user name="lianzgai" password="{noop}123" authorities="ROLE_ADMIN"></security:user>  </security:user-service>  </security:authentication-provider>  </security:authentication-manager>  </beans> 

导入springsecurity配置文件

将spring-security.xml配置到applicationContext.xml中

springsecurity的配置文件需要加载到spring容器中,所以可以通过import来导入

<import resource="classpath:spring-security.xml"></import>
配置好tomcat测试启动

注意:如果想要自己的自定义页面,要从这里这个<input name="_csrf" type="hidden" value="b90a7914-cbbd-4dc5-9bfe-0695ef9fc5b1" />入手。

现在就需要进行验证才能进入Hello World了。

如何将这个登录界面换成我们需要的呢?

准备好一个自己的 login , 首页home,失败fail页面!

配置认证信息:

<!--指定login.jsp页面可以被匿名访问 --> <security:intercept-url pattern="/login.jsp" access="permitAll()"/>
<!--                 拦截资源                 pattern="/**" 拦截所有的资源                 access="hasAnyRole('role1')" 表示只有role1这个角色可以访问资源              -->     <!--使用spring的el表达式来指定项目所有资源访问都必须有ROLE_USER或ROLE_ADMIN角色-->     <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"></security:intercept-url>      <!--指定自定义的认证页面-->     <security:form-login login-page="/login.jsp"                          login-processing-url="/login"                          authentication-success-forward-url="/home.jsp"                          authentication-failure-forward-url="/failure.jsp"/>      <!--关闭CSRF  false 开启-->     <security:csrf disabled="true"/>  </security:http>

上面的login页面就是登陆进来的页面,当我们的csrf关闭的时候,就可以直接进行登录了,但是时没有任何安全认证。false的时候就是开启!

 <form action="/login" method="post">     账号:<input type="text" name="username"><br>     密码:<input type="password" name="password"><br>     <input type="submit" value="登录"><br>     </form>

注意应该使用post方法。

当我们再次进行登录的时候会爆出403

403什么异常?这是SpringSecurity中的权限不足!这个异常怎么来的?还记得上面SpringSecurity内置认证页面源码中的那个_csrf隐藏input吗?问题就在这了!

我们查看源码:

this.requireCsrfProtectionMatcher.matches(request)方法

我们可以看出 GET HEAD TRACE OPTIONS 提交的数据不会csrf验证!

此时我们就明白了,自己的认证页面,请求方法为post,但却没有携带token,所以才会出现403权限不足的情况,我么你只需要在认证页面携带token请求!

<security:csrf disabled="false"/> //开启csrf保护机制

页面导入token
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>  <form action="/login" method="post">     账号:<input type="text" name="username"><br>     密码:<input type="password" name="password"><br>     <input type="submit" value="登录"><br>     <security:csrfInput/> </form>
注销也是一样
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> <html> <head>     <title>Title</title> </head> <body> <form method="post" action="/logout">     <h1>home界面</h1>     <security:csrfInput/>     <input type="submit" value="注销"> </form>  </body> </html>

此时我们的登录和注销页面就都很安全啦!!



全部评论

(0) 回帖
加载中...
话题 回帖