本案例基于springboot2.0.4,只说对登录验证的管理,不涉及权限的管理。因为学习新东西一下子太多,很容易乱。
       首先添加maven依赖,直接开启springboot自带的spring security即可。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

接下来配置config,需要继承WebSecurityConfigurerAdapter

@SpringBootConfiguration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {@Autowiredprivate MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;@Autowiredprivate MyAuthenticationFailHandler myAuthenticationFailHandler;@BeanUserDetailsService customUserService() {return new MyCustomUserService();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 使用自定义UserDetailsServiceauth.userDetailsService(customUserService()).passwordEncoder(new BCryptPasswordEncoder());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin().loginProcessingUrl("/user/login")// 自定义的登录验证成功或失败后的去向.successHandler(myAuthenticationSuccessHandler).failureHandler(myAuthenticationFailHandler)// 禁用csrf防御机制(跨域请求伪造),这么做在测试和开发会比较方便。.and().csrf().disable();}
}

如果验证数据是从数据库中获取的话还需要添加实现了UserDetailsService接口的类,操作数据使用的是mybatis,代码就不罗列了。

@Component
public class MyCustomUserService implements UserDetailsService {@Autowiredprivate SysUserMapper sysUserMapper;/*** 登陆验证时,通过username获取用户的所有权限信息* 并返回UserDetails放到spring的全局缓存SecurityContextHolder中,以供授权器使用*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {MyUserDetails myUserDetails = new MyUserDetails();myUserDetails.setUsername(username);SysUser sysUser = sysUserMapper.selectByKeyword(username);myUserDetails.setPassword(sysUser.getPassword());return myUserDetails;}
}

上面代码中的MyUserDetails是实现了UserDetails接口,自定义了返回对象。如果不使用MyUserDetails也可以,可以使用默认的User类,只不过验证就复杂点了,为了简化一些不必要的验证属性就自定义了一个UserDetails
下面是User的代码的一些属性。(是不是挺杂乱的对于初学者)

    private static final long serialVersionUID = 500L;private static final Log logger = LogFactory.getLog(User.class);private String password;private final String username;private final Set<GrantedAuthority> authorities;private final boolean accountNonExpired;private final boolean accountNonLocked;private final boolean credentialsNonExpired;private final boolean enabled;

这是自定义的MyUserDetails类,消除了一些不需要的属性对业务的影响。(只保留了3个属性)

@Component
public class MyUserDetails implements UserDetails {private String username;private String password;private Collection<? extends GrantedAuthority> authorities;public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {this.authorities = authorities;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return this.authorities;}@Overridepublic String getPassword() {return this.password;}@Overridepublic String getUsername() {return this.username;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}

还有两个登陆后去向类,这两个类就随意写了,根据业务需求来写即可。其实spring security本身也已经实现了默认的登录失败和登录成功去向,但是在前后端分离下,后端并不负责页面的跳转或者错误提示等。后端也会返回带有登录信息的Json格式的数据给前端,所以要想满足这些需求就需要实现AuthenticationFailureHandler和AuthenticationSuccessHandler接口。值得注意的是MyAuthenticationSuccessHandler类中的onAuthenticationFailure方法可以打印异常(错误)信息。

@Component
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {// 允许跨域httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");// 允许自定义请求头token(允许head跨域)httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");httpServletResponse.getWriter().write(200);}
}@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {// 允许跨域httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");// 允许自定义请求头token(允许head跨域)httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");httpServletResponse.getWriter().write(e.getMessage());}
}

接下来就是前端的登录代码,该action需要和WebSecurityConfiguration类中loginProcessingUrl(“/user/login”)的值一致。当然了下面的代码也可以用ajax来替代,不一定要用from表单登录。

<form action='/user/login' method='POST'><table><tr><td>User:</td><td><input type='text' name='username' value=''></td></tr><tr><td>Password:</td><td><input type='password' name='password'/></td></tr></table>
</form>

以上就是简单的spring security在前后端分离下的运用例子。不过光是这么写,不明白的人看了还是一头雾水,也不能充分展示spring security的强大。

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

重点再说下WebSecurityConfiguration类
在WebSecurityConfiguration类中需要把自定义的MyAuthenticationSuccessHandler和MyAuthenticationFailHandler去向类注入,并在loginProcessingUrl(“/user/login”)后面激活这两个类的使用

@Autowired
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Autowired
private MyAuthenticationFailHandler myAuthenticationFailHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginProcessingUrl("/user/login")// 自定义的登录验证成功或失败后的去向.successHandler(myAuthenticationSuccessHandler).failureHandler(myAuthenticationFailHandler)// 禁用csrf防御机制(跨域请求伪造),这么做在测试和开发会比较方便。.and().csrf().disable();
}

自定义MyUserDetailsService类也需要在WebSecurityConfiguration类中注入和激活使用

@Bean
UserDetailsService customUserService() {return new MyCustomUserService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {// 使用自定义UserDetailsServiceauth.userDetailsService(customUserService()).passwordEncoder(new BCryptPasswordEncoder());
}

上面的代码有个.passwordEncoder(new BCryptPasswordEncoder())这个意思就是指定密码加密的方式。这里采用的是BCrypt加密方式。换句话说,当spring security获取到你前端传过来的密码时,就自动用BCrypt加密密码,然后拿去和数据库密码匹对。所以在数据库里存的密码也得是用BCrypt加密后的密码。
       如果这么说,是不是也可以指定自定义加密方式呢。是可以的,实现也很简单,只要实现PasswordEncoder接口即可。在把.passwordEncoder(new BCryptPasswordEncoder())更改为.passwordEncoder(new MyPasswordEncoder())即可。

@Component
public class MyPasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence charSequence) {return SecurityUtil.encrypt(charSequence.toString());}@Overridepublic boolean matches(CharSequence charSequence, String s) {return encode(charSequence).equals(s);}
}

接下来说下这个

http.formLogin().loginProcessingUrl("/user/login")// 自定义的登录验证成功或失败后的去向.successHandler(myAuthenticationSuccessHandler).failureHandler(myAuthenticationFailHandler)// 禁用csrf防御机制(跨域请求伪造),这么做在测试和开发会比较方便。.and().csrf().disable();

关于这个一般来写的话都是有http.forLogin().loginPage(“/login”)啥的,这个是自定义登录页面,默认为/login。说白了就是你访问spring security保护的请求时候如果发现你没有登录,就会跳转到指定页面,使用默认或者不写的话spring security就会跳转到已经帮你写好了一个默认登录页面了。在前后端分离下,这个就不管了。loginProcessingUrl(“/user/login”)就是登录请求。

光是看上面的似乎有点囫囵吞枣,建议在看另一篇博文,主要分析登录验证的过程和一些源码的浅析。(写的不咋滴,但是认真看完后我觉得应该会有所收获)
SpringSecurity登录验证步骤和源码浅析

SpringSecurity前后端分离下对登录认证的管理相关推荐

  1. SpringBoot+SpringSecurity前后端分离+Jwt的权限认证(改造记录)

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/zzzgd_666/article/details/96444829 前言 一般来说,我们用Spr ...

  2. SpringBoot+SpringSecurity前后端分离+Jwt的权限认证改造记录!

    大家好,我是宝哥! 前言 一般来说,我们用SpringSecurity默认的话是前后端整在一起的,比如thymeleaf或者Freemarker,SpringSecurity还自带login登录页,还 ...

  3. SpringBoot+SpringSecurity前后端分离+Jwt的权限认证

    前言 一般来说,我们用SpringSecurity默认的话是前后端整在一起的,比如thymeleaf或者Freemarker,SpringSecurity还自带login登录页,还让你配置登出页,错误 ...

  4. php前后端分离登录,前后端分离下如何登录

    1 Web登录涉及到知识点 1.1 HTTP无状态性HTTP是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于 ...

  5. 前后端分离下微信登录高并发问题

    前后端分离 微信登录 高并发问题 目录 具体描述 成功解决的方案 具体描述 前端发起请求 ->(改进 插入 state: uuid) 后端拉起二维码 -> 用户确认 -> 微信回调 ...

  6. SpringSecurity前后端分离(包含token和验证码登录)

    SpringSecurity前后端分离 从上至下操作,直接上手SpringSecurity 文章目录 SpringSecurity前后端分离 1.项目环境 maven依赖 数据库表 2.自定义User ...

  7. SpringSecurity - 前后端分离简单实战 - 环境准备

    SpringSecurity 学习指南大全 文章目录 SpringSecurity - 前后端分离简单实战 - 环境准备 最好的理解方法 环境准备 技术前提 项目架构 项目创建 项目配置 数据库配置 ...

  8. 前后端分离之JWT用户认证

    前后端分离之JWT用户认证 在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时 ...

  9. 前后端分离使用 Token 登录解决方案

    前后端分离使用 Token 登录解决方案:https://juejin.im/post/5b7ea1366fb9a01a0b319612 转载于:https://www.cnblogs.com/byd ...

最新文章

  1. 创建function实现hive表结果导出到mysql
  2. winform频繁刷新导致界面闪烁解决方法
  3. 【深度学习】搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了
  4. OpenCV:OpenCV中的 parallel_for 和opencv parallel_for_
  5. 【流媒体FLV封装协议】
  6. 考研计算机网课辅导,考研计算机网课辅导哪个好
  7. Sites Table
  8. oracle tb级别数据量,备份TB级别Oracle数据库的一些技巧
  9. 微信公众平台消息接口开发(6)电话号码链接与网址链接
  10. JS正则表达式的分组匹配
  11. winform npoi 将execl转换成datatable,导入数据库
  12. nmap 扫描服务器开放了哪些端口
  13. html515vb,APx515 音频分析仪
  14. 文件转换swf/flv
  15. AD9173/AD9689 FMC采集板卡调试记录
  16. 深入理解Apache NIFI Run Duration
  17. 我们来试着解答一下下面的题目(8)(DP/多重部分和)
  18. ECCV2020-DETR笔记
  19. Flutter高仿微信-第36篇-单聊-语音通话
  20. 接口和抽象类的共性与区别

热门文章

  1. 三年啦,跳槽成功的Android开发面经总结!
  2. 托福百日冲刺—词汇(1)
  3. 如何查看操作系统的块大小
  4. 【英语】托福/GRE单词 近义/形近 分类汇总(更新中......)
  5. 移动应用测试篇(4)——App测试技术(2)
  6. (OpenCV — 7)ROI 区域图像叠加&图像混合
  7. arduino 土壤温湿度传感器_土壤湿度传感器测试-arduino篇
  8. centos 7.6 DNS——别名解析、泛域名解析、邮件交换
  9. 好的github源码记录(包括人脸...)
  10. MAVEN项目报错:An internal error occurred during: Updating Maven Project java.lang.NullPoint