课程目标
目标1:实现SpringSecurity入门小Demo
目标2:完成运营商登陆与安全控制功能
目标3:完成商家入驻
目标4:完成商家审核
目标5:完成商家系统登陆与安全控制功能
1.Spring Security框架入门
1.1 Spring Security简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
1.2 Spring Security入门小Demo
1.2.1最简单Demo
(1)创建工程spring-security-demo ,pom.xml内容
4.0.0
cn.itcast.demo
spring-security-demo
war
0.0.1-SNAPSHOT
4.2.4.RELEASE
org.springframework
spring-core
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework.security
spring-security-web
4.1.0.RELEASE
org.springframework.security
spring-security-config
4.1.0.RELEASE
javax.servlet
servlet-api
2.5
provided
org.apache.maven.plugins
maven-compiler-plugin
3.2
1.7
UTF-8
org.apache.tomcat.maven
tomcat7-maven-plugin
9090
/
(2)创建web.xml
contextConfigLocation
classpath:spring-security.xml
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
(3)创建index.html 内容略
(4)创建spring 配置文件spring-security.xml
此案例我们没有登录页,而是使用了系统自动生成的登陆页,效果如下:
配置说明:
intercept-url 表示拦截页面
/* 表示的是该目录下的资源,只包括本级目录不包括下级目录
/** 表示的是该目录以及该目录下所有级别子目录的资源
form-login 为开启表单登陆
use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,如果开启,则拦截的配置应该写成以下形式
1.2.2用户自定义登录页
实际开发中,我们不可能使用系统生成的登录页,而是使用我们自己的登录页。
(1)构建登陆页:
登陆
(2)构建登陆失败页 login_error.html(内容略)
(3)修改 spring 配置文件spring-security.xml
security=“none” 设置此资源不被拦截.
如果你没有设置登录页security=“none” ,将会出现以下错误
因为登录页会被反复重定向。
login-page:指定登录页面。
authentication-failure-url:指定了身份验证失败时跳转到的页面。
default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
csrf disabled=“true” 关闭csrf ,如果不加会出现错误
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
2.运营商系统登录与安全控制
2.1需求分析
完成运营商登陆功能
2.2登陆功能的实现
2.2.1配置文件
(1)修改pinyougou-manager-web的pom.xml ,添加依赖
org.springframework.security
spring-security-web
org.springframework.security
spring-security-config
(2)修改web.xml
contextConfigLocation
classpath:spring/spring-security.xml
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
(3)pinyougou-manager-web的spring目录下添加配置文件spring-security.xml
配置说明:
always-use-default-target:指定了是否在身份验证通过后总是跳转到default-target-url属性指定的URL。
如果你在系统中使用了框架页,需要设置框架页的策略为SAMEORIGIN
2.2.2登录页面
修改pinyougou-manager-web的 login.html
2.3主界面显示登陆人
2.3.1后端代码
在pinyougou-manager-web新建LoginController.java
package com.pinyougou.manager.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/login")
public class LoginController {
@RequestMapping("name")
public Map name(){
String name=SecurityContextHolder.getContext()
.getAuthentication().getName();
Map map=new HashMap();
map.put("loginName", name);
return map ;
}
}
2.3.2前端代码
(1)新建loginService.js
//登陆服务层
app.service('loginService',function($http){
//读取登录人名称
this.loginName=function(){
return $http.get('../login/name.do');
}
});
(2)新建indexController.js
app.controller('indexController' ,function($scope,$controller ,loginService){
//读取当前登录人
$scope.showLoginName=function(){
loginService.loginName().success(
function(response){
$scope.loginName=response.loginName;
}
);
}
});
页面上引入JS
指令
将页面上的测试用户 替换成 {{loginName}}
2.4退出登录
在pinyougou-manager-web的spring-security.xml的http节点中添加配置
加此配置后,会自动的产生退出登录的地址/logout,如果你不想用这个地址 ,你也可以定义生成的退出地址以及跳转的页面,配置如下
logout-url:退出的地址,会自动生成
logout-success-url:退出后跳转的地址
修改注销的链接
3.商家申请入驻
3.1需求分析
商家申请入驻,需要填写商家相关的信息。待运营商平台审核通过后即可使用使用。
3.2准备工作
(1)拷贝资源: 将“资源/静态原型/商家管理后台”下的页面拷贝到pinyougou-shop-web工程
(2)参照“运营商后台”构建js
(3)拷贝后端控制层代码
3.3前端代码
修改register.html 引入JS
指令
绑定表单(部分代码)
..............略
修改sellerController.js ,在保存成功后跳转到登陆页
//保存
$scope.add=function(){
sellerService.add( $scope.entity ).success(
function(response){
if(response.success){
location.href='shoplogin.html';
}else{
alert(response.message);
}
}
);
}
绑定“申请入驻”按钮
申请入驻
3.4后端代码
修改后端代码pinyougou-sellergoods-service的SellerServiceImpl类的add方法,设置默认状态为0
/**
* 增加
*/
@Override
public void add(TbSeller seller) {
seller.setStatus("0");
seller.setCreateTime(new Date());
sellerMapper.insert(seller);
}
4.商家审核
4.1需求分析
商家申请入驻后,需要网站运营人员在运营商后台进行审核,审核后商家才可以登陆系统。
状态值: 0:未审核 1:已审核 2:审核未通过 3:关闭
4.2商家待审核列表
修改seller_1.html
引入JS
指令
加入分页控件
循环
{{entity.sellerId}}
{{entity.name}}
{{entity.nickName}}
{{entity.linkmanName}}
{{entity.telephone}}
公司名称
{{entity.name}}
公司手机
{{entity.mobile}}
公司电话
{{entity.telephone}}
公司详细地址
{{entity.addressDetail}}
(2)列表的“详情”按钮
4.4商家审核
4.4.1 后端代码
(1)在pinyougou-sellergoods-interface工程的SellerService.java服务接口新增方法定义
/**
* 更改状态
* @param id
* @param status
*/
public void updateStatus(String sellerId,String status);
(2)在pinyougou-sellergoods-service的SellerServiceImpl.java新增方法
@Override
public void updateStatus(String sellerId, String status) {
TbSeller seller = sellerMapper.selectByPrimaryKey(sellerId);
seller.setStatus(status);
sellerMapper.updateByPrimaryKey(seller);
}
(3)在pinyougou-manager-web的SellerController.java新增方法
/**
* 更改状态
* @param sellerId 商家ID
* @param status 状态
*/
@RequestMapping("/updateStatus")
public Result updateStatus(String sellerId, String status){
try {
sellerService.updateStatus(sellerId, status);
return new Result(true, "成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "失败");
}
}
4.4.2 前端代码
修改pinyougou-manager-web的sellerService.js
//更改状态
this.updateStatus=function(sellerId,status){
return $http.get('../seller/updateStatus.do?sellerId='+sellerId+'&status='+status);
}
修改pinyougou-manager-web的sellerController.js
$scope.updateStatus=function(sellerId,status){
sellerService.updateStatus(sellerId,status).success(
function(response){
if(response.success){
$scope.reloadList();//刷新列表
}else{
alert("失败");
}
}
);
}
修改按钮,调用方法