摘要:建立一个模块继承上一个模块然后添加依赖解决打包时找不到文件建立数据源文件数据库连接相关修改配置数据源和整合,以及事务管理自动扫描扫描时跳过注解的类控制器扫描配置文件这里指向的是
1.建立一个模块继承上一个模块然后添加依赖
junit
junit
4.11
test
org.springframework
spring-test
4.2.8.RELEASE
org.mybatis
mybatis
3.4.4
org.mybatis
mybatis-spring
1.3.0
com.alibaba
druid
1.1.8
mysql
mysql-connector-java
5.1.41
src/main/java
**/*.xml
org.apache.maven.plugins
maven-compiler-plugin
1.8
1.8
2.建立数据源文件application.properties
#数据库连接相关
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/security-demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username = root
jdbc.password = 123456
3.修改applicationContext.xml,配置数据源,和mybatis整合,以及事务管理
目录结构,我这里测试mybatis时放在同一包出问题,所以选择了分别扫描xml和mapper接口
数据库,总共建立了5张表,用户表,角色表,用户角色对应表,权限表,权限角色对应表,关系也很简单,一个用户有多个角色,一个角色也可以有多个用户拥有,一个角色有多种权限,一个权限也可以由多个角色掌握,这个看自己怎么设计,其中用户表最重要,这里面包含了用户的基本信息
/*
Navicat MySQL Data Transfer
Source Server : security
Source Server Version : 50719
Source Host : localhost:3306
Source Database : security-demo
Target Server Type : MYSQL
Target Server Version : 50719
File Encoding : 65001
Date: 2019-08-02 10:25:48
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for sys_authorization
-- ----------------------------
DROP TABLE IF EXISTS `sys_authorization`;
CREATE TABLE `sys_authorization` (
`id` int(11) NOT NULL,
`authorizationName` varchar(50) DEFAULT NULL,
`authorizationMark` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_authorization
-- ----------------------------
INSERT INTO `sys_authorization` VALUES ("1", "产品查询", "ROLE_LIST_PRODUCT");
INSERT INTO `sys_authorization` VALUES ("2", "产品添加", "ROLE_ADD_PRODUCT");
INSERT INTO `sys_authorization` VALUES ("3", "产品修改", "ROLE_UPDATE_PRODUCT");
INSERT INTO `sys_authorization` VALUES ("4", "产品删除", "ROLE_DELETE_PRODUCT");
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`id` int(11) NOT NULL,
`roleName` varchar(50) DEFAULT NULL,
`roleDescription` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ("1", "普通用户", "普通用户");
INSERT INTO `sys_role` VALUES ("2", "管理员", "管理员");
-- ----------------------------
-- Table structure for sys_role_authorization
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_authorization`;
CREATE TABLE `sys_role_authorization` (
`roleId` int(11) NOT NULL,
`authorizationId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_role_authorization
-- ----------------------------
INSERT INTO `sys_role_authorization` VALUES ("1", "1");
INSERT INTO `sys_role_authorization` VALUES ("1", "2");
INSERT INTO `sys_role_authorization` VALUES ("2", "1");
INSERT INTO `sys_role_authorization` VALUES ("2", "2");
INSERT INTO `sys_role_authorization` VALUES ("2", "3");
INSERT INTO `sys_role_authorization` VALUES ("2", "4");
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`realname` varchar(50) DEFAULT NULL,
`createDate` date DEFAULT NULL,
`lastLoginTime` date DEFAULT NULL,
`enabled` int(11) DEFAULT NULL,
`accountNonExpired` int(11) DEFAULT NULL,
`accountNonLocked` int(11) DEFAULT NULL,
`credentialsNonExpired` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ("1", "jojo", "$2a$10$VCvgzml/DNzBTkjsPlImDuZp38sNZB7cEmsNgFIWBm/Vtpn0Q3Bj.", "张三", "2019-06-26", "2019-08-01", "1", "1", "1", "1");
INSERT INTO `sys_user` VALUES ("2", "jack", "$2a$10$W1T2Z5dUMIgBfxvFdBOWuusq8Nwke/cQydxDFemsbTh0PjGeZCiMC", "李四", "2019-07-30", "2019-08-01", "1", "1", "1", "1");
-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`userId` int(11) NOT NULL,
`roleId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ("1", "1");
INSERT INTO `sys_user_role` VALUES ("2", "2");
基本配置完成
在mapper文件夹下建立UserMapper接口
package com.ty.mapper;
import com.ty.pojo.Authorization;
import com.ty.pojo.User;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @Author:TY
* @Descroption:
* @Date: Created in 11:34 2019/8/1
* @Modificd By:
*/
public interface UserMapper {
@Select("select * from sys_user")
List findAll();
/**
* 查询当前用户对象
*/
public User findByUserName(String username);
/**
* 查询当前用户的权限
*/
List findAuthorizationByUserName(String username);
/**
* 修改密码
*/
@Update("update sys_user set password=#{password} where username=#{username}")
public void updatePassword(User user);
}
UserMapper.xml:
想要测试就这样
在MainController里面添加一个验证码接口(生成验证码网上都有,这里就不列出了)
@RequestMapping("/imageCode")
public void imageCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ImageCodeProcessor.send(new ServletWebRequest(request,response),new ImageCodeGenerator().generate(new ServletWebRequest(request)));
ImageCode generate = new ImageCodeGenerator().generate(new ServletWebRequest(request));
HttpSession session = request.getSession();
System.out.println("生成的验证码为:"+generate.getCode());
session.setAttribute("key",generate.getCode());
response.setContentType("image/jpeg");
// 将图像输出到Servlet输出流中。
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(generate.getImage(), "jpeg", sos);
sos.close();
}
pojo包中的User对象,里面添加了一个权限的字段,是user表中没有的,并且User对象实现了UserDetails接口,实现了其中的方法,方便后面security使用
package com.ty.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class User implements UserDetails{
private Integer id;
private String username;
private String password;
private String realname;
private java.util.Date createDate;
private java.util.Date lastLoginTime;
private boolean enabled;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
//用户拥有的所有权限
List authorities=new ArrayList<>();
@Override
public String toString() {
return "User{" +
"username="" + username + """ +
", realname="" + realname + """ +
", authorities=" + authorities +
"}";
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List getAuthorities() {
return authorities;
}
public void setAuthorities(List authorities) {
this.authorities = authorities;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isAccountNonExpired() {
return accountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
}
其它表就直接用idea自带的工具:数据库生成pojo类执行就行了
连接数据库点击
springSecurity.xml:里面都有注释,而且也不难,一看就会系列
MyUserDetailService :这里就动态在数据库里面动态查询了用户的权限,然后因为之前我们的User类实现了UserDetails接口,所以当返回我们自己从数据库查询的用户然后返回的时候,springSecurity会自己拿着用户输入的信息和我们数据库中的做一个比对,对比上了则认证成功
package com.ty.security;
import com.ty.mapper.UserMapper;
import com.ty.pojo.Authorization;
import com.ty.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:TY
* @Descroption:
* @Date: Created in 17:09 2019/8/1
* @Modificd By:
*/
public class MyUserDetailService implements UserDetailsService{
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user=null;
System.out.println(username);
if(username!=null&&!username.equals(""))
{
user = userMapper.findByUserName(username);
if (user!=null)
{
//获取用户权限
List permList = userMapper.findAuthorizationByUserName(username);
List authorizations=new ArrayList<>();
for (Authorization perm:permList)
{
GrantedAuthority authority=new SimpleGrantedAuthority(perm.getAuthorizationMark());
authorizations.add(authority);
}
user.setAuthorities(authorizations);
}
return user;
}
return user;
}
}
然后我们自定义成功后的处理器MySuccessAthenticationHandler
package com.ty.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:TY
* @Descroption:
* @Date: Created in 19:43 2019/8/1
* @Modificd By:
*/
public class MySuccessAthenticationHandler implements AuthenticationSuccessHandler {
private static final ObjectMapper objectMapper=new ObjectMapper();
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
Map map=new HashMap();
map.put("success",true);
String result = objectMapper.writeValueAsString(map);
httpServletResponse.setContentType("text/json;charset=utf-8");
httpServletResponse.getWriter().write(result);
}
}
失败处理器:
package com.ty.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:TY
* @Descroption:
* @Date: Created in 21:23 2019/7/31
* @Modificd By:
*/
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler{
private ObjectMapper objectMapper=new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
Map map=new HashMap();
map.put("success",false);
map.put("errorMsg",e.getMessage());
String result = objectMapper.writeValueAsString(map);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(result);
}
}
登录的时候是先验证验证码,验证码通过在验证用户名和密码
验证码的拦截器
package com.ty.security;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @Author:TY
* @Descroption:,他能够确保在一次请求只通过一次filter,而不需要重复执行
*
* @Date: Created in 21:22 2019/8/1
* @Modificd By:
*/
public class ImageCodeAuthenticationFilter extends OncePerRequestFilter {
private AuthenticationFailureHandler authenticationFailureHandler;
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
this.authenticationFailureHandler = authenticationFailureHandler;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//判断当前请求,是否为登录请求,
if (request.getRequestURI().contains("/login"))
{
try {
//校验验证码
//表单填的验证码
String imageCode = request.getParameter("imageCode");
System.out.println("表单填的验证码为:"+imageCode);
//系统生成的验证码
HttpSession session = request.getSession();
String sesstionCode = (String) session.getAttribute("key");
System.out.println("session里的验证码为:"+sesstionCode);
if(imageCode==null||imageCode.equals(""))
{
throw new ImageCodeException("验证码不能为空");
}
if(!imageCode.equals(sesstionCode))
{
throw new ImageCodeException("验证码错误");
}
}catch (AuthenticationException e){
//交给自定义的
authenticationFailureHandler.onAuthenticationFailure(request,response,e);
return;
}
}
filterChain.doFilter(request,response);
}
}
验证码异常类
package com.ty.security;
import org.springframework.security.core.AuthenticationException;
/**
* @Author:TY
* @Descroption:
* @Date: Created in 21:47 2019/8/1
* @Modificd By:
*/
public class ImageCodeException extends AuthenticationException {
public ImageCodeException(String msg, Throwable t) {
super(msg, t);
}
public ImageCodeException(String msg) {
super(msg);
}
}
注意:我们是把验证码过滤器加在UserNamePasswordAuthenticationFilter前面的,当我们的验证码抛出异常,验证码没通过时会抛一个ImageCodeException,这个类继承了AuthenticationException ,所以当抛出异常之后会到我们自定义的MyAuthenticationFailureHandler,这样就可以向前端返回异常的数据
login.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: TY
Date: 2019/7/31
Time: 19:14
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录页面
用户名或密码错误
用户名:
密 码:
验证码:
记住我
- $(function () {
- $("#LoginButton").click(function () {
- $.post("/login", $("#loginForm").serialize(), function (data) {
- if (data.success) {
- window.location.href = "${pageContext.request.contextPath}/product/index";
- } else {
- alert("登录失败:" + data.errorMsg);
- }
- }, "json");
- })
- })
- window.onload = function () {
- var date = new Date();
- $("#imgcheck").click(function () {
- $(this).attr("src", "/imageCode?temp=" + date);
- });
- }
如果要根据权限显示前端内容,就在pom.xml引入
</>code
org.springframework.security
spring-security-taglibs
4.2.3.RELEASE
index.jsp
</>code
<%--
Created by IntelliJ IDEA.
User: TY
Date: 2019/7/31
Time: 16:49
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
首页
欢迎${username}登陆
以下是网站的功能
商品添加
商品修改
商品查询
商品删除
**最后如果想要获取认证通过后的用户的信息,任何地方都能获取
可以使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()
</>code
/**
* 首页 SecurityContextHolder.getContext().getAuthentication().getPrincipal()可以在任何地方获取当前用户的信息
*/
@RequestMapping("index")
public String index(Model model)
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal!=null)
{
if(principal instanceof UserDetails)
{
UserDetails userDetails= (UserDetails)principal;
model.addAttribute("username",userDetails.getUsername());
}
}
return "index";
}
**
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/75767.html
摘要:什么是是一个能够为基于的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它来自于,那么它与整合开发有着天然的优势,目前与对应的开源框架还有。通常大家在做一个后台管理的系统的时候,应该采用判断用户是否登录。 什么是SpringSecurity ? Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全...
摘要:开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章系列处理登录请求前后端分离一使用完美处理权限问题前后端分离二使用完美处理权限问题前后端分离三中密码加盐与中异常统一处理 开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章! Spring Boo...
摘要:创建一个工程在里面添加依赖,依赖不要随便改我改了出错了好几次都找不到原因可以轻松的将对象转换成对象和文档同样也可以将转换成对象和配置 1.创建一个web工程2.在pom里面添加依赖,依赖不要随便改,我改了出错了好几次都找不到原因 UTF-8 1.7 1.7 2.5.0 1.2 3.0-alpha-1 ...
摘要:在上一篇基本配置了一些文件中,基本可以在文件中指定用户名和密码来进行实现的验证,这次和一起来配合使用加入的配置文件别名在的中配置数据源查找配置事物然后建立层,和层以及对应这里省略实 在上一篇基本配置了一些文件中,基本可以在文件中指定用户名和密码来进行实现SpringSecurity的验证,这次和mynatis一起来配合使用 加入mybatis的配置文件: mybatis-config....
阅读 3223·2019-08-30 15:56
阅读 1344·2019-08-29 15:20
阅读 1675·2019-08-29 13:19
阅读 1618·2019-08-29 13:10
阅读 3494·2019-08-26 18:27
阅读 3169·2019-08-26 11:46
阅读 2347·2019-08-26 11:45
阅读 4021·2019-08-26 10:12
极致性价比!云服务器续费无忧!
Tesla A100/A800、Tesla V100S等多种GPU云主机特惠2折起,不限台数,续费同价。
NVIDIA RTX 40系,高性价比推理显卡,满足AI应用场景需要。
乌兰察布+上海青浦,满足东推西训AI场景需要