目录 🌻🌻
一、Spring Security 框架入门
忽略结构图往下看
1.1 Spring Security 简介
Spring Security [ sprɪŋ sɪˈkjʊərəti ]
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
相关依赖
<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>
1.2 Spring Security 入门 Demo
1.2.1 最简单 Demo
(1)创建工程spring-security-demo
, 并且引入pom.xml 内容
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zql</groupId>
<artifactId>spring-security-demo</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<properties>
<webVersion>3.0</webVersion>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<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>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- 指定端口 -->
<port>9090</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2)创建 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>
<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>
注意过滤器名字必须固定为:springSecurityFilterChain
webapp下面创建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
登录成功
</body>
</html>
resources下面创建 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">
<!-- 配置 favicon.ico不进行安全拦截-->
<!--<http pattern="/favicon.ico" security="none"/>-->
<!-- 页面拦截规则 -->
<http use-expressions="false">
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<form-login/>
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="123" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
启动tomcat
浏览器登录 http://localhost:9090/index.html
出现下面 👇🏾👇🏾
在 spring-security.xml
对应位置中添加 👇🏾👇🏾
<!-- 配置 favicon.ico不进行安全拦截-->
<http pattern="/favicon.ico" security="none"/>
再次访问 localhost:9090/index.html
- 配置说明:
- intercept-url 表示拦截页面
- /* 表示的是该目录下的资源,只包括本级目录不包括下级目录
- /** 表示的是该目录以及该目录下所有级别子目录的资源
- form-login 为开启表单登陆
- use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,
- 拦截的配置应该写成以下形式 👇🏾👇🏾
ROLE_ADMIN:必须验证具备该角色后才能访问,注意角色名称必须以ROLE_开头
再次访问 localhost:9090/index.html
1.2.2 用户自定义登录页
开发中,我们不可能使用系统生成的登录页,而是使用我们自己的登录页。
(1)webapp下面 构建登陆页:login.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登陆</title>
</head>
<body>
<form action='/login' method='POST'>
<table>
<tr>
<td>用户名:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>密码:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="登陆" /></td>
</tr>
</table>
</form>
</body>
</html>
注意:登录提交地址/login 改地址由SpringSecurity生成,提交方法必须是POST
(2)构建登陆失败页 login_error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
登录失败
</body>
</html>
(3)修改 spring 配置文件 spring-security.xml
浏览器登录页的登录 http://localhost:9090/login.html
解决: 👇🏾👇🏾 添加 <csrf disabled="true"></csrf>
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
则 🤞🤞
在 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">
<!-- 配置 favicon.ico不进行安全拦截-->
<http pattern="/favicon.ico" security="none"/>
<!-- 登录页和登录失败页不进行安全拦截 -->
<!-- <http pattern="/login.html" security="none"/>
<http pattern="/login_error.html" security="none"/>-->
<!-- 页面拦截规则 -->
<http use-expressions="false">
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<form-login login-page="/login.html"
default-target-url="/index.html" always-use-default-target="true"
authentication-failure-url="/login_error.html"/>
<csrf disabled="true"></csrf>
<!--
login-page:指定登录页面。
default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
always-use-default-target:设置为 true 用户一直发送到指定的页面。
authentication-failure-url:指定了身份验证失败时跳转到的页面。
csrf disabled="true" 关闭csrf ,如果不加会出现错误
-->
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="123" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
访问 :http://localhost:9090/login.html
因为拦截了所以登录页会被反复重定向。
- login-page:指定登录页面。
- default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
- authentication-failure-url:指定了身份验证失败时跳转到的页面。
- always-use-default-target
– 如果设置成"true",用户会一直转发到default-target-url指定的位置,无论他们在登录页面之前访问的什么位置。 对应UsernamePasswordAuthenticationFilter的alwaysUseDefaultTargetUrl属性。- csrf disabled=“true” 关闭csrf ,如果不加会出现错误
解决 :
<!-- 登录页和登录失败页不进行安全拦截 -->
<http pattern="/login.html" security="none"/>
<http pattern="/login_error.html" security="none"/>
再次访问 :http://localhost:9090/login.html
登录成功显示 : 用户名 :admin 密码:123
登录失败显示 : 比如 用户名 :admin 密码:1234
二、运营商系统登录与安全控制
2.1 需求分析
完成运营商登陆功能
2.2 登陆功能的实现
2.2.1 配置文件
(1)修改youlexuan_manager_web的 pom.xml ,添加依赖
<!--spring security相关依赖包-->
<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>
(2)修改web.xml ,增加SpringSecurity过滤器
<!--SpringSecurity过滤器-->
<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>
(3)youlexuan_manager_web 的 spring目录下添加配置文件 spring-security.xml
并copy 1.2.2 (2)做修改 如下:
<?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">
<!-- 配置 favicon.ico不进行安全拦截-->
<http pattern="/favicon.ico" security="none"/>
<!-- 以下页面不被拦截 -->
<http pattern="/login.html" security="none"></http>
<http pattern="/css/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<!-- 页面拦截规则 -->
<http use-expressions="false">
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<form-login login-page="/login.html"
default-target-url="/admin/index.html" always-use-default-target="true"
authentication-failure-url="/login.html"/>
<csrf disabled="true"></csrf>
<!--
login-page:指定登录页面。
always-use-default-target:设置为 true 用户一直发送到指定的页面。
default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
authentication-failure-url:指定了身份验证失败时跳转到的页面。
csrf disabled="true" 关闭csrf ,如果不加会出现错误
-->
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="123" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
完整 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">
<!-- 配置 favicon.ico不进行安全拦截-->
<http pattern="/favicon.ico" security="none"/>
<!-- 以下页面不被拦截 -->
<http pattern="/login.html" security="none"></http>
<http pattern="/css/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<!-- 页面拦截规则 -->
<http use-expressions="false">
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<form-login login-page="/login.html"
default-target-url="/admin/index.html" always-use-default-target="true"
authentication-failure-url="/login.html"/>
<csrf disabled="true"></csrf>
<!--
login-page:指定登录页面。
always-use-default-target:设置为 true 用户一直发送到指定的页面;指定了是否在身份验证通过后总是跳转到default-target-url属性指定的URL。
default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
authentication-failure-url:指定了身份验证失败时跳转到的页面。
csrf disabled="true" 关闭csrf ,如果不加会出现错误
-->
<!--如果你在系统中使用了框架页,需要设置框架页的策略为SAMEORIGIN-->
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
</http>
<!-- 认证管理器 -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="123" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
2.2.2 登录页面
修改youlexuan_manager_web的 login.html
<div id="profile" class="tab-pane active">
<form id="loginform" action="/login" method="post">
<div class="input-prepend"><span class="add-on loginname"></span>
<input name="username" id="prependedInput" type="text" placeholder="邮箱/用户名/手机号" class="span2 input-xfat">
</div>
<br/>
<div class="input-prepend"><span class="add-on loginpwd"></span>
<input name="password" id="prependedInput" type="password" placeholder="请输入密码" class="span2 input-xfat">
</div><br/>
<div class="setting">
<div id="slider">
<div id="slider_bg"></div>
<span id="label">>></span> <span id="labelTip">拖动滑块验证</span>
</div>
</div>
<div class="logined">
<a class="sui-btn btn-block btn-xlarge btn-danger" onclick="document:loginform.submit()" target="_blank">登 录</a>
</div>
</form>
</div>
解决 :
<!--如果你在系统中使用了框架页,需要设置框架页的策略为SAMEORIGIN-->
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
SAMEORIGIN:frame页面的地址只能为同源域名下的页面
2.3 主界面显示登陆人
2.3.1 后端代码
在youlexuan_manager_web新建 LoginController.java
package com.zql.sellergoods.controller;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:Daniel
* @Version 1.0
*/
@RestController
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/name")
public Map name(){
String name = SecurityContextHolder.getContext().getAuthentication().getName();
//System.out.println("================="+name);
Map map = new HashMap<>();
map.put("loginName",name);
return map;
}
}
测试 :http://localhost:9101/login/name.do
2.3.2 前端代码
(1)在youlexuan_manager_web / webapp / js / service下面新建 loginService.js
//登陆服务层
app.service('loginService',function ($http) {
//读取登录人名称
this.loginName = function () {
return $http.get('../login/name.do');
}
});
(2)在youlexuan_manager_web / webapp / js / controller下面新建 indexController.js
app.controller('indexController',function ($scope,$controller,loginService) {
//读取当前登录人
$scope.showLoginName = function () {
loginService.loginName().success(function(response){
$scope.loginName = response.loginName;
})
}
});
(3)在youlexuan_manager_web / webapp / admin / index.html 添加指令并引入下面 js
<body class="hold-transition skin-green sidebar-mini" ng-app="youlexuan" ng-controller="indexController" ng-init="showLoginName()" >
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<script type="text/javascript" src="../js/base.js"></script>
<script type="text/javascript" src="../js/service/loginService.js"></script>
<script type="text/javascript" src="../js/controller/indexController.js"></script>
登录后的效果显示:http://localhost:9101/login.html
用户名 admin 密码 123
2.4 退出登录
在youlexuan_manager_web的 spring-security.xml 的 http节点中添加配置 <logout/>
加此配置后,会自动的产生退出登录的地址/logout
修改注销的链接 youelxuan_manager_web / webapp / admin / index.html
别人总结的👉🏾👉🏾 Spring Security