目录

  • 不用过滤器(使用json传参方式登录)
    • SecurityConfig配置
    • 账号密码
    • 手机号验证码
    • 使用
  • 使用过滤器实现(使用form表单传参方式登录)

不用过滤器(使用json传参方式登录)

SecurityConfig配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;/*** spring security配置*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {/** 认证失败 处理类 */@Autowiredprivate AuthenticationEntryPointImpl unauthorizedHandler;/** 退出 处理类 */@Autowiredprivate LogoutSuccessHandlerImpl logoutSuccessHandler;/** jwt token认证过滤器 */@Autowiredprivate JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;/** 手机验证码 认证器 */@Autowiredprivate CaptchaAuthenticationProvider captchaAuthenticationProvider;/** 账号密码 认证器*/@Autowiredprivate UserNameAuthenticationProvider userNameAuthenticationProvider;/*** 认证管理 AuthenticationManager*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.csrf().disable().cors().and()// 基于token,所以不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 认证失败处理类.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()// 过滤请求.authorizeRequests()// 允许匿名访问.antMatchers(antMatchersAnonymous()).anonymous().antMatchers(HttpMethod.GET, antMatchersPermitAll()).permitAll()// 除上面外的所有请求全部需要鉴权认证.anyRequest().authenticated().and().headers().frameOptions().disable();// 退出处理httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);// 添加JWT filter(必须配置与UsernamePasswordAuthenticationFilter之前)httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);}// 允许匿名访问urlprivate String[] antMatchersAnonymous() {return new String[]{"/login"  };}// 不需要任何限制url(静态资源)private String[] antMatchersPermitAll() {return new String[]{"/*.html"};}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 添加认证器// 新增短信验证码验证auth.authenticationProvider(captchaAuthenticationProvider);// 账号密码登录验证auth.authenticationProvider(userNameAuthenticationProvider);}/*** 密码加密规则 强散列哈希加密实现(密码加密算法)*/@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder() {return new BCryptPasswordEncoder();}
}

账号密码

UserNameAuthenticationProvider 账号密码认证器

import java.util.Collections;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;/*** 用户名密码认证器*/
@Slf4j
@Component
public class UserNameAuthenticationProvider implements AuthenticationProvider {/** 进行账号认证实现 */@Autowiredprivate UserDetailsService userDetailsService;/** 密码加密规则 */@Autowiredprivate PasswordEncoder bCryptPasswordEncoder;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {long time = System.currentTimeMillis();log.info("用户名/密码 开始登录验证 time:{}", time);String username = authentication.getName();String password = authentication.getCredentials().toString();// 1、去调用自己实现的UserDetailsService,返回UserDetailsUserDetails userDetails = userDetailsService.loadUserByUsername(username);// 2、密码进行检查,这里调用了PasswordEncoder,检查 UserDetails 是否可用。if (Objects.isNull(userDetails) || !bCryptPasswordEncoder.matches(password, userDetails.getPassword())) {throw new BadCredentialsException("账号或密码错误");}// 3、返回经过认证的AuthenticationUsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(userDetails, null, Collections.emptyList());result.setDetails(authentication.getDetails());log.info("用户名/密码 登录验证完成 time:{}, existTime:{}", time, (System.currentTimeMillis() - time));return result;}@Overridepublic boolean supports(Class<?> authentication) {boolean res = UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);log.info("用户名/密码 是否进行登录验证 res:{}", res);return res;}
}

手机号验证码

CaptchaAuthenticationToken 短信验证码认证凭证

import java.util.Collection;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;/*** 短信验证码认证凭证*/
public class CaptchaAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;private final Object principal; // 手机号private String captcha;         // 验证码/*** 此构造函数用来初始化未授信凭据.** @param principal* @param captcha*/public CaptchaAuthenticationToken(Object principal, String captcha) {super(null);this.principal = principal;this.captcha = captcha;setAuthenticated(false);}/*** 此构造函数用来初始化授信凭据.** @param principal* @param captcha* @param authorities*/public CaptchaAuthenticationToken(Object principal, String captcha, Collection<? extends GrantedAuthority> authorities) {super(authorities);this.principal = principal;this.captcha = captcha;super.setAuthenticated(true);}public Object getCredentials() {return this.captcha;}public Object getPrincipal() {return this.principal;}public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials() {super.eraseCredentials();captcha = null;}
}

CaptchaAuthenticationProvider 短信验证码认证器

import java.util.Collections;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;/*** 短信验证码认证器*/
@Slf4j
@Component
public class CaptchaAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate UserDetailsService userDetailsService;/** 验证码验证服务 */@Autowiredprivate ICaptchaService captchaService;/*** 进行验证码认证** @param authentication* @return* @throws AuthenticationException*/@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {long time = System.currentTimeMillis();log.info("手机验证码 开始登录验证 time:{}", time);String phone = authentication.getName();String rawCode = authentication.getCredentials().toString();// 1. 手机验证码验证captchaService.validate("admin:account:login:key:", phone, rawCode);// 1.根据手机号获取用户信息UserDetails userDetails = userDetailsService.loadUserByUsername(phone);if (Objects.isNull(userDetails)) {throw new BadCredentialsException("当前手机号不存在");}// 3、返回经过认证的AuthenticationCaptchaAuthenticationToken result = new CaptchaAuthenticationToken(userDetails, null, Collections.emptyList());result.setDetails(authentication.getDetails());log.info("手机验证码 登录验证完成 time:{}, existTime:{}", time, (System.currentTimeMillis() - time));return result;}@Overridepublic boolean supports(Class<?> authentication) {boolean res = CaptchaAuthenticationToken.class.isAssignableFrom(authentication);log.info("手机验证码 是否进行登录验证 res:{}", res);return res;}
}

ICaptchaService

/*** 验证码*/
public interface ICaptchaService {/*** 缓存验证码** @param key 缓存前缀key* @param phone* @param code*/public void setCaptcha(String key, String phone, String code);/*** 验证验证码** @param key 缓存前缀key* @param phone* @param code * CustomException 自定义异常*/public boolean validate(String key, String phone, String code) throws CustomException;}

CaptchaServiceImpl 实现类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** 验证码*/
@Component
public class CaptchaServiceImpl implements ICaptchaService {@Autowiredprivate RedisUtil redisUtil;@Overridepublic void setCaptcha(String key, String phone, String code) {// 有效期5分钟redisUtil.set(key + phone, code, 300);}@Overridepublic boolean validate(String key, String phone, String code) throws CustomException {if (StrUtils.isBlank(phone) || StrUtils.isBlank(code)) {throw new CustomException("验证验证码参数为空", 300);}// 获取缓存数据Object v = redisUtil.get(key + phone);if (null == v) {throw new CustomException("验证码过期,请重新获取", 300);}// 验证是否正确if (!code.equalsIgnoreCase(String.valueOf(v))) {throw new CustomException("验证码错误", 300);}// 验证通过 清除缓存redisUtil.delete(key + phone);return true;}
}

使用

下面为简版登录 具体写法以公司为准

@Slf4j
@RestController
public class LoginController {/*** 用户名密码 登录 * LoginBody 实体字段 (username)用户名, (password)用户密码/验证码, (type)登录类型 1-密码登录, 2-短信验证码登录 默认1*/@PostMapping("/login")public Boolean login(@RequestBody LoginBody loginBody) {loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getType());return true;}
}

LoginService

import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;/*** 登录校验方法**/
@Slf4j
@Component
public class SysLoginService {@Resourceprivate AuthenticationManager authenticationManager;/*** 登录验证** @param username 用户名* @param password 密码* @param type     登录类型 1-密码登录, 2-短信验证码登录 默认1* @return 结果*/public String login(String username, String password, Integer type) {// 用户验证Authentication authentication = null;try {if (null == type || type == 1) {// 密码登录authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));} else {// 短信验证码登录authentication = authenticationManager.authenticate(new CaptchaAuthenticationToken(username, password));}} catch (Exception e) {log.error("登录验证异常", e);// 登录异常 自己处理业务逻辑}return null;}
}

使用过滤器实现(使用form表单传参方式登录)

推荐看这篇文章 https://www.felord.cn/captchaAuthenticationFilter.html

主要是自己实现过滤器 过滤器继承AbstractAuthenticationProcessingFilter

Spring Security多种登录方式相关推荐

  1. Springboot + Spring Security多种登录方式:账号用户名登录+微信网页授权登录

    一.概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路,最重要的一点是要实现微信登录通过Spring Security安全框架时,不需要验证账号.密码. 二.准备工作 要 ...

  2. SpringBoot + Spring Security多种登录方式:账号+微信网页授权登录

    一.概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路,最重要的一点是要实现微信登录通过Spring Security安全框架时,不需要验证账号.密码. 二.准备工作 要 ...

  3. Spring Boot Security 多种登录方式集成配置思路及方法 账号用户名登录+微信网页授权登录

    概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路 前情提要 本思路完全抛弃Spring Security的配置式账号密码登录模式,采用完全独立的Filter.Provi ...

  4. 你有没有遇到要实现多种登录方式的场景丫 一起来看看咯 Spring Security 实现多种登录方式,如常规方式外的邮件、手机验证码登录

    你好丫,我是博主宁在春,一起加油吧!!! 不知道, 你在用Spring Security的时候,有没有想过,用它实现多种登录方式勒,这次我的小伙伴就给我提了一些登录方面的需求,需要在原有账号密码登录的 ...

  5. spring security+jwt 登录认证

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

  6. Spring Security自定义登录验证及登录返回结果

    Spring Security自定义登录验证及登录返回结果 一.功能描述 二.处理逻辑 简单流程 自定义UserDetails 自定义UserDetailsDAO 自定义UserDetailsServ ...

  7. spring security导致登录后从https跳转至http解决方案

    1. 项目为spring boot项目,由原来的http连接更换为https连接,因项目中配置的了spring security,登录被spring security拦截重定向后会跳转到http 解决 ...

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

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

  9. Spring Security:自定义登录页面

    本文来说下Spring Security中如何自定义登录页面 文章目录 准备工作 自定义登录界面 本文小结 准备工作 添加模板引擎 这里使用了thymeleaf模板引擎,在pom.xml进行添加: & ...

最新文章

  1. android jason动画,Android 动画之Lottie动画使用
  2. 另一种思考:为什么不选JPA、MyBatis,而选择JDBCTemplate?
  3. 太阳电池板特性实验_汕头市通风柜厂家报价-广州中增实验室设备
  4. XML转JSON的javascript代码
  5. sap实施和开发哪个前景_2021年了!还不知道 SAP顾问的职业前景?
  6. 【渝粤教育】国家开放大学2018年春季 8634-21TAndroid智能手机编程 参考试题
  7. 玩客云pc端_玩客云电脑客户端-玩客云pc端下载 v1.4.5.112官方版--pc6下载站
  8. Hadoop完全分布式安装Kafka
  9. python 设计模式之装饰器模式 Decorator Pattern
  10. 最大表示法--环形字符串最大字典序(HDU 5442)
  11. 【转载】linux环境下大数据网站搬家
  12. 基于IdentityServer4的单点登录——IdentityServer
  13. git pull 提示当前不在某个分支上解决办法
  14. 原子操作:CAS、TAS、TTAS、FAA浅析
  15. [转帖]*野外生活手册~
  16. 凸优化理论(一)数学优化问题的分类
  17. 计算机桌面壁纸怎么保存,电脑桌面背景图片保存路径
  18. Android 11 : 隐私和安全
  19. 微信公共号推广技巧、快速涨粉丝的7大技巧总结
  20. 坑爹的MediaPlayer.isPlaying()

热门文章

  1. 99%IT人都应该收藏的学习,找资料必备之网站
  2. 鼎捷易飞7.0、8.0、9.0、9.0.12等各版本下载地址
  3. 计算机管理usb出现问号,usb里有个问号
  4. matlab htk tools,基于HTK调用MATLAB的语音识别的研究
  5. 洛谷 P2534 [AHOI2012]铁盘整理(IDA*(dfs+迭代加深+估值函数))
  6. ffmpeg简单操作mp3与mp4
  7. hfss史密斯图_教你如何在天线设计上使用HFSS仿真软件?
  8. 最新UI易/赞支付系统源码+PHP开发的
  9. r6220 虚拟服务器,网件r6220设置页面打不开 其实很简单
  10. Android 使用ViewPager2+ExoPlayer+VideoCache 实现仿抖音视频翻页播放