目录

一:安全权限框架的选取

二:功能

三:登录登出

四:代码注释

1.将登陆交由Spring security完成

2.前台明文密码加密,与数据库比对

3.关键配置

4.自定义用户异常

5.ajax请求处理陈宫和失败的

6.MD5加密和对象转成json就不用我说了吧

五:记住我功能的原理和实现

1.原理

2.代码

六:验证码功能的实现

七:三次错误密码锁定账户


一:安全权限框架的选取

目前主流的安全权限框架有:shiro和security以及自定义权限框架。本人在之前都是使用的shiro框架,在一定程度上shiro框架具有简单而又通用的优势。但是这里我为什么启用security框架呢?

首先从名字可以看出security是spring 家族的一员,具有天然无缝整合spring的优势。在之前本人接触到了springcloud-aouth2中使用了security来控制权限,因此这里我们本章就基于这个security框架。

这里我们将从以下几个方面来解决spring security涉及到的内容

(1)登录登出配置

(2)权限的管理

(3)记住我的功能

(4)登录超时

...

二:功能

spring  security中对于登录登出功能的功能包含:

(1)登录交由security来检测

(2)权限配置交由sercurity来配置

(3)存储用户登录的缓存(即在spring容器的上下文中都可以在这里取得当前用户的信息)

三:登录登出

这里主要是3个配置以及主要的作用如下图所示

四:代码注释

1.将登陆交由Spring security完成

这里基本上没有什么的,结合上图就能看懂

package com.config.Seurity.service;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;import org.apache.tomcat.util.security.MD5Encoder;
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 org.springframework.stereotype.Service;import com.moudle.user.model.Role;
import com.moudle.user.model.User;
import com.moudle.user.model.UserRole;
import com.moudle.user.service.UserRoleService;
import com.moudle.user.service.UserService;import commons.utils.Md5Utils;/** 自定义用户登录授权service*/
@Service("userDetailsService")
public class LoginService implements  UserDetailsService{@Autowiredprivate UserService  userService;@Autowiredprivate UserRoleService  userroleSerivce;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {List<User>  userList = userService.login(username, null);if (userList == null || userList.isEmpty()) {throw new UsernameNotFoundException("该用户不存在!");}//添加权限UserRole  userRole=new UserRole();userRole.setUserId(userList.get(0).getFkUserId());List<Role> roleList=userroleSerivce.findUserRoleList(userRole).get(0).getRoleList();Collection<GrantedAuthority> authorities = new ArrayList<>();for(Role role:roleList) {authorities.add(new SimpleGrantedAuthority(role.getRoleCode()));}return new org.springframework.security.core.userdetails.User(userList.get(0).getUserName(),userList.get(0).getPassword(), authorities);}}

2.前台明文密码加密,与数据库比对

这里也没什么好说的,就是注意前台输入的面加密方式与存入数据库密码的方式,一致

package com.config.Seurity.pwdEnder;import org.springframework.security.crypto.password.PasswordEncoder;import commons.utils.Md5Utils;
import lombok.extern.slf4j.Slf4j;/*** 自定义加密,在这里给前台密码加密,并且与数据库比对* ClassName: MyPasswordEncoder * Function: 一句话描述功能. * auth: monxz* date: 2019年8月28日 下午5:34:32 ***/@Slf4j
public class MyPasswordEncoder  implements PasswordEncoder {@Overridepublic String encode(CharSequence charSequence) {return Md5Utils.hash(charSequence.toString());}@Overridepublic boolean matches(CharSequence charSequence, String s) {log.info("前端铭文密码:"+charSequence.toString()+",数据库密码:"+s);return s.equals(Md5Utils.hash(charSequence.toString()));}
}

3.关键配置

注意:我这里登录方法是以ajax提交的,如果用form表单提交的释放form表单登录注释,ajax登录添加注释即可

package com.config.Seurity.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import com.config.Seurity.hander.AjaxSuccessHander;
import com.config.Seurity.hander.AjaxfailHander;
import com.config.Seurity.pwdEnder.MyPasswordEncoder;
import com.config.Seurity.service.LoginService;/*** spring security的配置* ClassName: SecurityConfig * Function: 一句话描述功能. * auth: monxz* date: 2019年8月28日 上午10:04:50 ***/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{@Autowiredprivate LoginService loginService;//登录执行的逻辑@Autowiredpublic void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(loginService).passwordEncoder(new MyPasswordEncoder());}//配置信息@Overrideprotected void configure(HttpSecurity http) throws Exception { String[]  allowedUrl= {"/api/**"};//配置访问权限http.authorizeRequests()//允许匿名访问(如api).antMatchers(allowedUrl).permitAll()                               //其他地址的访问均需验证权限.anyRequest().authenticated();//配置登录以及成功失败的处理方式http.formLogin()                     //指定登录页是"/view/login"   .loginPage("/view/login").permitAll()    ////ajax方式登录                       .successHandler(new AjaxSuccessHander()).failureHandler(new AjaxfailHander()).loginProcessingUrl("/login").usernameParameter("username")  //ajax请求必须的.passwordParameter("password");//form表单请求登录
//                      .defaultSuccessUrl("/view/index")       //登录成功后默认跳转到路径"//注销 ,直接访问   ip:port/logout        http .logout().logoutSuccessUrl("/view/login")          //退出登录后跳转到登录主界面".permitAll();//跨域以及其他的一些配置http .csrf().disable()   // 关闭CSRF跨域.headers().frameOptions().sameOrigin();  // 允许加载frame子菜单}//静态资源@Overridepublic void configure(WebSecurity web) throws Exception {String[] allowedRes= {"/static/**","/css/**","/js/**","/my/**","/img/**","/ajax/**","favicon.ico"};// 设置拦截忽略文件夹,可以对静态资源放行web.ignoring().antMatchers(allowedRes);}}

4.自定义用户异常

package com.config.Seurity.exception;/*** 用户名不存在* ClassName: UsernameNotFoundException * Function: 一句话描述功能. * auth: monxz* date: 2019年8月28日 上午10:17:02 ***/public class UserException extends RuntimeException{private String retCd ;  //异常对应的返回码private String msgDes;  //异常对应的描述信息public UserException() {super();}public UserException(String message) {super(message);msgDes = message;}public UserException(String retCd, String msgDes) {super();this.retCd = retCd;this.msgDes = msgDes;}public String getRetCd() {return retCd;}public String getMsgDes() {return msgDes;}}

5.ajax请求处理陈宫和失败的

package com.config.Seurity.hander;import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;import commons.json.JSON;import lombok.extern.slf4j.Slf4j;/*** 登录失败的ajax* ClassName: AjaxSuccessHander * Function: 一句话描述功能. * auth: monxz* date: 2019年8月28日 下午3:58:29 ***/
@Slf4j
public class AjaxfailHander extends SimpleUrlAuthenticationFailureHandler{@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {String message = "账号或密码输入错误,请重新输入!";response.setCharacterEncoding("utf-8");response.setContentType("application/json; charset=utf-8");PrintWriter writer = response.getWriter();Map<String, Object> map=new HashMap<String, Object>();map.put("success", false);map.put("message", message);writer.write(JSON.mapJson(map));}
}
package com.config.Seurity.hander;import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.tomcat.util.http.ResponseUtil;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;import com.alibaba.druid.support.json.JSONUtils;import commons.json.JSON;
import commons.json.JSONObject;
import commons.result.DataResult;
import lombok.extern.slf4j.Slf4j;/*** 登录成功的ajax* ClassName: AjaxSuccessHander * Function: 一句话描述功能. * auth: monxz* date: 2019年8月28日 下午3:58:29 ***/
@Slf4jpublic class AjaxSuccessHander extends SimpleUrlAuthenticationSuccessHandler{@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setCharacterEncoding("utf-8");response.setContentType("application/json; charset=utf-8");PrintWriter writer = response.getWriter(); Map<String, Object>  map=new HashMap<String, Object>();map.put("success", true);writer.write(JSON.mapJson(map));}
}

6.MD5加密和对象转成json就不用我说了吧

五:记住我功能的原理和实现

1.原理

这个原理图是从网上百度的。。。但是很容易看明白

2.代码

(1)前端页面

注意点就2个

(2)SercurityConfig中配置

加入数据库的应用

@Autowiredprivate DataSource dataSource;

添加到数据库㕜

//记住我功能的Token存储在数据库中@Beanpublic PersistentTokenRepository persistentTokenRepository() {JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();// 配置数据源jdbcTokenRepository.setDataSource(dataSource);// 第一次启动的时候自动建表(可以不用这句话,自己手动建表,源码中有语句的)jdbcTokenRepository.setCreateTableOnStartup(true);return jdbcTokenRepository;}

配置信息中配置

//配置信息@Overrideprotected void configure(HttpSecurity http) throws Exception { String[]  allowedUrl= {"/api/**"};//配置访问权限http.authorizeRequests()//允许匿名访问(如api).antMatchers(allowedUrl).permitAll()                               //其他地址的访问均需验证权限.anyRequest().authenticated();//配置登录以及成功失败的处理方式http.formLogin()                     //指定登录页是"/view/login"   .loginPage("/view/login").permitAll()    ////ajax方式登录                       .successHandler(new AjaxSuccessHander()).failureHandler(new AjaxfailHander()).loginProcessingUrl("/login").usernameParameter("username")  //ajax请求必须的.passwordParameter("password");//form表单登录
//                      .defaultSuccessUrl("/view/index")       //登录成功后默认跳转到路径"//注销 ,直接访问   ip:port/logout        http .logout().logoutSuccessUrl("/view/login")          //退出登录后跳转到登录主界面".deleteCookies()                     //有记住我功能,删除cookie.permitAll();//记住我http.rememberMe().tokenRepository(persistentTokenRepository()).tokenValiditySeconds(60);//跨域以及其他的一些配置http .csrf().disable()   // 关闭CSRF跨域.headers().frameOptions().sameOrigin();  // 允许加载frame子菜单}

注意:当你的数据库存在persistent_logins表,请注释掉 第一次启动自动建表下的那句话

说明=====》这里我们目前只是实现功能,在后面我们会将这里的tokne集中存放在redis中的

六:验证码功能的实现

本来是想做一个基于spring security的验证码功能的,但是考虑到那种验证码功能是真的恶心,这里直接使用前段js插件sliderImgPuzzle.js实现图片拖动时验证,关于后端的验证,会在后面的网关模块做修改。这里直接贴出我下载的地址吧

https://github.com/chen9091/jq_slideImage

七:三次错误密码锁定账户

这里先说明一下思路吧,使用缓存,设置失效时间(即为锁定时间),因为考虑到上面的一些问题,我会在下下张整合到redis中一起实现。

从零开始java安全权限框架篇(一):spring security配置登录登出的配置相关推荐

  1. Spring Security 自定义接口登出

    Spring Security 自定义接口登出 使用Security提供的工具,在接口内登出用户. 工具类代码 // 注入 tokenStore@Autowiredprivate final Toke ...

  2. Spring Security(十):登出Logout

    一:Spring Security默认退出处理逻辑 使当前session失效 清楚与当前用户相关的remember-me记录 清空当前的SecurityContext 重定向到登录页 二:Spring ...

  3. SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解

    1.预置演示环境 这个演示环境继续沿用 SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境. 2.自定义配置类 ...

  4. java 接口权限控制_手把手教你搞定权限管理,结合Spring Security实现接口的动态权限控制!...

    SpringBoot实战电商项目mall(30k+star)地址:github.com/macrozheng/- 摘要 权限控管理作为后台管理系统中必要的功能,mall项目中结合Spring Secu ...

  5. 框架使用SpringBoot + Spring Security Oauth2 +PostMan

    框架使用SpringBoot + Spring Security Oauth2  主要完成了客户端授权  可以通过mysql数据库读取当前客户端表信息进行验证,token存储在数据库中 1.引入依赖 ...

  6. spring security+jwt 登录认证

    spring security+jwt 登录认证 1.综述 2.版本与环境 3.架构 4.数据库认证逻辑图 5.案例 security+jwt 5.1引入依赖 5.2新建工具类 5.2新建组件类 5. ...

  7. spring Security 重复登录配置无效的问题

    关于spring Security重复登录的配置,百度一大堆,我这里就不啰嗦了. 今天碰到 按照网上的配置,但是 感觉配置无效,同一用户还是可以登录,不知道为什么,开始以为是自己配置的又问题.再三确认 ...

  8. Spring Security MVC登录注销示例教程

    Spring Security MVC登录注销示例教程 今天我们将了解Spring Security Login Example.在阅读这篇文章之前,请先阅读我在"Spring 4 Secu ...

  9. SSM项目图书馆管理系统,适合新人练手和毕设参考,功能首页展示 系统注册登录登出 用户管理 权限控制管理 书籍管理 图书借阅管理 个人借阅记录管理 书籍详细信息展示等

    图书馆管理系统,系统采用B/S架构 系统采用框架:java+maven+stringboot+mybatis+mysql-plus+boostart(前端界面) 首页展示 内容后台管理 菜单权限管理 ...

最新文章

  1. Linux进阶 vim grep sed awk 正则表达式
  2. Windows 7新睹为快!!
  3. eeglab教程系列(7)-数据叠加平均{1}(Data averaging)
  4. 《Shell脚本学习指南》第一章 背景知识
  5. 剑指Offer_35_数组中的逆序对
  6. python 判断数据类型,是否与已知相同
  7. 图论 —— 网络流 —— 最大流 —— Dinic 算法
  8. 【小松教你手游开发】【unity实用技能】InvalidOperationException: ou
  9. 如何在ASP.NET中生成HTML5离线Web应用
  10. 数据结构_满二叉树、完全二叉树、二叉排序树、平衡二叉树
  11. java 数组随机抽取_Java利用数组随机抽取幸运观众
  12. 超星尔雅学习通情商与智慧人生 答案 满分版
  13. 什么是RS-232-C接口与什么是RS-485接口?
  14. windows下docker 挂载数据卷报错 Error response from daemon: user declined directory sharing
  15. win10壁纸存储位置_这是Windows 10存储其默认壁纸的位置
  16. 高德h5地图api接口_概述-URI API | 高德地图API
  17. AOP(面向切面)原理及使用
  18. JS逆向之巨量星图sign签名
  19. Python 抖音无水印视频下载
  20. opencv-python 指静脉的手指轮廓提取实现

热门文章

  1. ES6 新增数组的方法使用介绍
  2. 八千调色相机 -- 照片调色必备工具,蒸汽波复古特效滤镜
  3. GPU编程优化篇-姜雪伟-专题视频课程
  4. 基于Python的bilibili会员购数据爬取
  5. 选择什么时间周期做交易合适?
  6. MySQL存储引擎深入理解
  7. 树莓派系统用TF卡选购需谨慎
  8. 一个测试tf卡性能的脚本
  9. PyQt学习随笔:QTableWidget的信号signal简介
  10. 《安富莱嵌入式周报》第288期:微软推出Arm主控PC套件,WiFi信号捕获阵列,下一代雷电4技术,u-boot之父Wolfgang De离开了我们,向大神致敬