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>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值