十九、商城 - 运营商登录-Spring Security(7)

一、Spring Security 框架入门

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(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

相关依赖

maven依赖下载

<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

在这里插入图片描述

Spring Security 源码

二、运营商系统登录与安全控制

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">&nbsp;&nbsp;</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

本节及之前项目所有源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel521-Spark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值