深入浅出Spring Security

一、Spring Security简介     

  在 Web 应用开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。因此,从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中。

        那么我们为什么需要安全权限管理呢?

        1.安全性:误操作、人为破坏、数据泄漏等
        2.数据隔离:不同的权限能看到及操作不同的数据
        3.明确职责:运营、客服等不同角色

        在安全权限管理方面,有两个十分优秀的安全权限框架,他们是Apache公司的Shiro框架,和Spring公司的Spring Security框架,今天我们主要讲解Spring Security框架的入门,不比较两者的优缺点

   Spring Security 设计是基于框架内大范围的依赖的,可以被划分为以下几块。

  • Web/Http 安全:这是最复杂的部分。通过建立 filter 和相关的 service bean 来实现框架的认证机制。当访问受保护的 URL 时会将用户引入登录界面或者是错误提示界面。

  • 业务对象或者方法的安全:控制方法访问权限的。

  • AuthenticationManager:处理来自于框架其他部分的认证请求。

  • AccessDecisionManager:为 Web 或方法的安全提供访问决策。会注册一个默认的,但是我们也可以通过普通 bean 注册的方式使用自定义的 AccessDecisionManager。

  • AuthenticationProvider:AuthenticationManager 是通过它来认证用户的。

  • UserDetailsService:跟 AuthenticationProvider 关系密切,用来获取用户信息的。

二、Spring Security + Spring MVC入门应用

2.1创建一个maven工程,选择war

2.2配置pom.xml

<dependencies>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>4.1.0.RELEASE</version>
		</dependency>

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

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>


	</dependencies>
	<build>
	  <plugins>		
	      <!-- java编译插件 -->
		  <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.2</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
		  </plugin>      
	      <plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<configuration>
					<!-- 指定端口 -->
					<port>9090</port>
					<!-- 请求路径 -->
					<path>/</path>
				</configuration>
	  	  </plugin>
	   </plugins>  
    </build>

2.3创建web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">	

  	 <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>
	
    <!--配置spring security-->
	 <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>

2.4创建spring-security.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 use-expressions="false">
		<intercept-url pattern="/**" access="ROLE_USER" />
		<form-login/>	
	</http>

	<!-- 认证管理器 -->
	<authentication-manager>
		<authentication-provider>
			<user-service>
				<user name="admin" password="123456" authorities="ROLE_USER"/>
			</user-service>		
		</authentication-provider>	
	</authentication-manager>
</beans:beans>

2.5创建一个index.html,在里面随便输入一句话,我这里是  欢迎进入神奇的spring security世界~~

2.6运行maven,这里我们没有写登录页,spring security会自动为我们创建一个登陆页面

我们随便输入账号密码

输入正确的admin和123456

这里有可能会报这么一个错误,那是因为spring security自带的图标没有加载到,重新登陆即可

这样,我们的入门小demo就完成了,仔细想想,我们好像没有做什么事情,甚至连登陆页面也没有画,那么spring security框架究竟为我们做了哪些事情呢?这里我们详细讲解一下spring-security.xml文件

intercept-url 表示拦截页面  

/*  表示的是该目录下的资源,只包括本级目录不包括下级目录

/** 表示的是该目录以及该目录下所有级别子目录的资源

form-login  为开启表单登陆

use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,如果开启,则拦截的配置应该写成以下形式

 

这里我们来自己定义一个登陆页面,spring-security配置文件如下

<?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 pattern="/login.html" security="none"></http>
	<http pattern="/login_error.html" security="none"></http>

	<!-- 页面的拦截规则   是否启用SPEL表达式 true/false 默认为true-->
	<!-- 如果为true,access格式需为hasRole('ROLE_USER') -->
	<http use-expressions="false">
		<!--/** 根目录与其子目录全部拦截  access:角色名称 ROLE_  -->
		<!-- 当前用户必须用ROLE_USER的角色才可以访问根目录及其子目录所有资源 -->
		<intercept-url pattern="/**" access="ROLE_USER"/>
		<!-- 开启表单登陆功能  default-target-url:登陆成功去到那个页面,authentication-failure-url:登陆失败渠道那个页面-->
		<form-login login-page="/login.html" default-target-url="/index.html" authentication-failure-url="/login_error.html"/>
		
		<!-- 这里不设置会被反复重定向 -->
		<csrf disabled="true"/>
	</http>
	
	<!-- 认证管理器 -->
	<authentication-manager>
		<authentication-provider>
			<user-service>
				<!-- 用来配置当前系统的用户  authorities:用户属于哪一个角色-->
				<user name="admin" password="123456" authorities="ROLE_USER"/>
			</user-service>
		</authentication-provider>
	</authentication-manager>
		
</beans:beans>

自定义一个login.html页面

<body>
  	--欢迎登陆我的系统--
  	<form action="/login" method="post">
  		用户名:<input type="text" name="username"><br>
  		密   码:<input type="password" name="password"><br>
  		<button>登陆</button>
  	</form>
  </body>

在自定义一个login_error.html页面

 
  <body>
		用户名或密码错误
  </body>

登陆

输入错误的账号密码

输入正确的账号密码

注意:

spring-security.xml中 <csrf disabled="true"/> 这个配置我们不写的话,我们将出现如下错误

我们输入正确的账号密码

原因:CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。如果不配置,这里会造成一直重定向

猜你喜欢

转载自blog.csdn.net/weixin_41110459/article/details/81953261