Spring security全集2-ssm整合Spring security

目录

 

前言

1.什么是RBAC模型权限控制

2.RBAC权限模型的数据库表如何设置

3.整合ssm+Spring security4

3.1引入依赖

3.2web文件

3.3applicationContent.xml文件

3.4spring-security.xml文件

4.异步处理登录成功和登录失败

5.密码加密

6.自定义图形验证码

通过jsp页面制作验证码imagecode.jsp

加载验证码控制器

在spring security配置文件中放心imagecode请求

在登陆页面加载验证码

自定义过滤器比对验证码

Spring security配置文件中引入过滤器

7.remember –me

登陆页面添加remember-me

在security中配置remember的bean以及

使用remember-me

8.security标签库的使用

加入标签库的依赖

在jsp页面导入标签库

使用标签

9.获取登陆后的用户信息


前言

用心写好每一篇文章,真心对待每一个读者

文章首发地址: www.javayihao.top

首发公众号: java一号

1.什么是RBAC模型权限控制

RBAC主要是用户、角色、以及权限三者关系,用户与角色相关联,角色与权限相关联,用户通过成为适当角色的成员而得到这些角色的权限。简化了系统中权限的控制

2.RBAC权限模型的数据库表如何设置

总共需要用户表 、角色表、 权限表三张基础表,另外还有用户和角色是多对多有一张中间表,角色和权限是多对多有一张中间表,如下数据库sss的sql语句


-- ----------------------------

-- Table structure for sys_permission

-- ----------------------------

DROP TABLE IF EXISTS `sys_permission`;

CREATE TABLE `sys_permission` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `permName` varchar(255) DEFAULT NULL,

  `permTag` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;


-- ----------------------------

-- Records of sys_permission

-- ----------------------------

INSERT INTO `sys_permission` VALUES ('1', '增加商品', 'ROLE_ADD');

INSERT INTO `sys_permission` VALUES ('2', '删除商品', 'ROLE_DELETE');

INSERT INTO `sys_permission` VALUES ('3', '修改商品', 'ROLE_UPDATE');

INSERT INTO `sys_permission` VALUES ('4', '查询商品', 'ROLE_LIST');


-- ----------------------------

-- Table structure for sys_role

-- ----------------------------

DROP TABLE IF EXISTS `sys_role`;

CREATE TABLE `sys_role` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `roleName` varchar(255) DEFAULT NULL,

  `roleDesc` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;


-- ----------------------------

-- Records of sys_role

-- ----------------------------

INSERT INTO `sys_role` VALUES ('1', '普通用户', '普通用户');

INSERT INTO `sys_role` VALUES ('2', '管理员 ', '管理员');


-- ----------------------------

-- Table structure for sys_role_permission

-- ----------------------------

DROP TABLE IF EXISTS `sys_role_permission`;

CREATE TABLE `sys_role_permission` (

  `role_id` int(11) NOT NULL,

  `perm_id` int(11) NOT NULL,

  PRIMARY KEY (`role_id`,`perm_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ----------------------------

-- Records of sys_role_permission

-- ----------------------------

INSERT INTO `sys_role_permission` VALUES ('1', '1');

INSERT INTO `sys_role_permission` VALUES ('1', '2');

INSERT INTO `sys_role_permission` VALUES ('2', '3');

INSERT INTO `sys_role_permission` 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(255) DEFAULT NULL,

  `realname` varchar(255) DEFAULT NULL,

  `password` varchar(255) 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=utf8mb4;


-- ----------------------------

-- Records of sys_user

-- ----------------------------

INSERT INTO `sys_user` VALUES ('1', '123', '张三', '123', '2019-05-13', '2019-05-13', '1', '1', '1', '1');

INSERT INTO `sys_user` VALUES ('2', '456', '李四', '123', '2019-05-13', '2019-05-13', '1', '1', '1', '1');


-- ----------------------------

-- Table structure for sys_user_role

-- ----------------------------

DROP TABLE IF EXISTS `sys_user_role`;

CREATE TABLE `sys_user_role` (

  `user_id` int(11) NOT NULL,

  `role_id` int(11) NOT NULL,

  PRIMARY KEY (`user_id`,`role_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ----------------------------

-- Records of sys_user_role

-- ----------------------------

INSERT INTO `sys_user_role` VALUES ('1', '1');

INSERT INTO `sys_user_role` VALUES ('2', '2');

3.整合ssm+Spring security4

3.1引入依赖


    
    
        org.springframework
        spring-core
        ${spring.version}
    
    
        org.springframework
        spring-web
        ${spring.version}
    
    
        org.springframework
        spring-webmvc
        ${spring.version}
    
    
    
        org.springframework
        spring-jdbc
        ${spring.version}
    
    
    
        org.springframework.security
        spring-security-web
        ${spring.security.version}
    
    
        org.springframework.security
        spring-security-config
        ${spring.security.version}
    
    
    
        jstl
        jstl
        ${jstl.version}
    
    
        javax.servlet
        servlet-api
        ${servlet.version}
        provided
    
    
    
        com.fasterxml.jackson.core
        jackson-databind
        2.9.5
    
    
    
        org.mybatis
        mybatis
        3.4.4
    
    
    
        org.mybatis
        mybatis-spring
        1.3.0
    
    
    
        com.alibaba
        druid
        1.1.7
    
    
    
        mysql
        mysql-connector-java
        5.1.41
    

3.2web文件



    
    
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
    
    
        springSecurityFilterChain
        /*
    
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
        contextConfigLocation
        
            classpath:applicationContent.xml
            
            classpath:spring-security.xml
        
    
    
    
        DispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:Springmvc.xml
        
        
        1
    
    
        DispatcherServlet
        /
    

3.3applicationContent.xml文件



    
    
    
    
        
        
        
        
        
        
    
    
    
        
        
        
        
    
    
    
        
    
    
    
        
    
     
    
    

3.4spring-security.xml文件



    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
    
    
    
        
    
    

完整代码,请关注微信公众号  java一号  回复ssms原文获取

访问项目

Spring security全集2-ssm整合Spring security_第1张图片

使用用户123访问能够正常访问添加和删除页面,但是当访问查询和修改页面,会显示权限不足的提示,说明我们整合spring security4成功。

4.异步处理登录成功和登录失败

上面的登录是同步的过程,下面通过异步处理登录业务,首先和spring security入门篇一样,自定义myAuthenticationFailureHandler和MyAuthenticationSuccessHandler两个业务类,代码如下
package com.javayihao.top.sss.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 lupenghu
 * @Des
 * @Date create in 11:112019/5/28
 * @
 */
public class myAuthenticationFailureHandler implements AuthenticationFailureHandler {
    //使用spring默认支持的json数据处理依赖包,将对象转成json格式的字符串
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
        Map map = new HashMap<>();
        map.put("success", false);
        String jsonStr = objectMapper.writeValueAsString(map);
        response.setContentType("text/json;Charset=utf-8");
        response.getWriter().write(jsonStr);
    }
}

package com.javayihao.top.sss.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 lupenghu
 * @Des
 * @Date create in 10:572019/5/28
 * @
 */
/*
如果使用异步登陆,
自定义成功类需要实现AuthenticationSuccessHandler成功接口
 */
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    //使用spring默认支持的json数据处理依赖包,将对象转成json格式的字符串
    private ObjectMapper objectMapper = new ObjectMapper();

    /*
    authentication代表认证成功后的信息
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        Map map = new HashMap<>();
        map.put("success", true);
        String jsonStr = objectMapper.writeValueAsString(map);
        response.setContentType("text/json;Charset=utf-8");
        response.getWriter().write(jsonStr);
    }
}

在Spring security配置文件中引用



    
    
        
        
        
        
        
        
        
        
        
       
        
              
        
        
        
    
    
    
        
    
    
    

     
    

登陆页面使用ajax异步登陆

<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    登陆
    


登陆界面

用户名或密码错误

用户名 密码
<%--如果使用异步登陆--%>

5.密码加密

Spring security提供了一个接口PasswordEncoder用来对用户密码加密,可以查看一下这个接口源代码

public interface PasswordEncoder {

//对输入的密码进行加密,通过hash算法加盐值实现的
    String encode(CharSequence var1);

//匹配密码
    boolean matches(CharSequence var1, String var2);
}

测试代码

public static void main(String[] args) {
    //使用PasswordEncoder接口的实现类BCryptPasswordEncoder()加密字符串
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    System.out.println(encoder.encode("123456"));
    //结果是: $2a$10$dlZ4vbMw/qPqoLIgCF8A/OUMi.1qKRL6.wh88Aj.l1dzzW7faIXC6
 }

 

我们把数据库中用户名是123的用户密码改成上面加密后的结果

然后在只需在spring security配置文件中配置如图所示的代码,即可达到密码加密与比对

Spring security全集2-ssm整合Spring security_第2张图片

6.自定义图形验证码

通过jsp页面制作验证码imagecode.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="java.awt.image.BufferedImage"%>
<%@page import="javax.imageio.ImageIO"%>
<%@ page import="java.awt.*" %>
<%@ page import="java.io.OutputStream" %>
<%
    int width=80;
    int height=32;
    BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
    Graphics g = image.getGraphics();
    g.setColor(new Color(0xDCDCDCD));
    g.fillRect(0,0,width,height);
    g.drawRect(0,0,width-1,height-1);
    Random random = new Random();
    String hash1 = Integer.toHexString(random.nextInt());
    for(int i=0;i<50;i++){
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        g.drawOval(x,y,0,0);
    }
    String capstr = hash1.substring(0,4);
    session.setAttribute("key",capstr);
    g.setColor(new Color(0,100,0));
    g.setFont(new Font("Candara", Font.BOLD,24));
    g.drawString(capstr,8,24);
    g.dispose();
    response.setContentType("image/jpeg");
    out.clear();
    out=pageContext.pushBody();
    OutputStream stream =  response.getOutputStream();
    ImageIO.write(image,"jpeg",stream);
    stream.close();
%>

加载验证码控制器

@RequestMapping("/imageCode")
public String imagecode(){
    return "imagecode";
}

 

在spring security配置文件中放心imagecode请求

 

在登陆页面加载验证码

验证码

自定义过滤器比对验证码

package com.javayihao.top.sss.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 java.io.IOException;

/**
 * @Author lupenghu
 * @Des
 * @Date create in 21:232019/5/28
 * @
 */
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{
                //用户输入的验证码
                final  String imageCode =request.getParameter("image");
                System.out.println(imageCode+"======================");
                //获取系统生成的验证码
                String key = (String) request.getSession().getAttribute("key");
                if(imageCode==null){
                    throw  new ImageCodeException("验证码必须输入");
                }
                if(!imageCode.trim().equals(key.trim())){
                    throw  new ImageCodeException("验证码必须一致");
                }
            }catch (AuthenticationException e){
                //交给自定义authenticationFailureHandler处理
                authenticationFailureHandler.onAuthenticationFailure(request,response,e);
                return;
            }
        }
        filterChain.doFilter(request,response);
    }
}

Spring security配置文件中引入过滤器





 
     
 

 

7.remember –me

security中提供了remember-me的验证功能

登陆页面添加remember-me

注意name必须是security中的remember-me

记住我

在security中配置remember的bean以及



    
    
    

使用remember-me




8.security标签库的使用

加入标签库的依赖


    org.springframework.security
    spring-security-taglibs
    ${spring.security.version}

 

在jsp页面导入标签库

<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%>

 

使用标签

security中有以下四个标签

标签1 :
标签2:
标签3:
标签4:

主要常用的是标签3(有指定权限的才可以看见标签内容),比如只有有ROLE_ADD权限的才才可以看到添加


    添加

9.获取登陆后的用户信息

//获取登陆后的用户信息 ,实际获取的就是UserDetail对象
Object prin = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (prin != null) {
    if (prin instanceof UserDetails) {
        UserDetails userDetails = (UserDetails) prin;
        String username = userDetails.getUsername();
        model.addAttribute("username", username);
    }
}

关注微信公众号 java一号 获取更多java编程资料 实战项目 实战视频教程!

你可能感兴趣的:(java知识)