springboot整合spring security的使用

朱雀 2022-12-27 08:24 206阅读 0赞

文章目录

    • 1.项目准备
    • 2.实现自定义登录
      • 失败跳转
      • 前后端分离的问题

1.项目准备

pom
这里使用的是springboot2.2.11.RELEASE

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-security</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>

2.实现自定义登录

由于他自带了拦截页面 我们想要实现自己的登录表单

这时候 需要有一个继承了WebSecurityConfigurerAdapter的类

来实现带http参数的configure()方法

这里要说明一点 如果 写了loginPage()则不用再写controller里的请求方法了 直接跳转

  1. @Configuration
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Override
  4. protected void configure(HttpSecurity http) throws Exception {
  5. //表单提交
  6. http.formLogin()
  7. //提交表单跳转的页面请求 与表单里的action对应
  8. .loginProcessingUrl("/login")
  9. //表单所在的页面
  10. .loginPage("/login.html")
  11. ;
  12. }
  13. }

login页面表单

  1. <form action="/login" method="post">
  2. 用户名<input type="text" name="username"><br>
  3. 密码<input type="text" name="password"><br>
  4. <input type="button" value="登录">
  5. </form>

丑是丑好歹效果有了
在这里插入图片描述

我们再新增点内容 实现登录 具体的功能看注释 这个是最精简版的了

最终跳转的方法tomain也要是post请求 这点需要注意

  1. @Override
  2. protected void configure(HttpSecurity http) throws Exception {
  3. //表单提交
  4. http.formLogin()
  5. //提交表单跳转的页面请求 与表单里的action对应
  6. .loginProcessingUrl("/login")
  7. //表单所在的页面
  8. .loginPage("/login.html")
  9. //成功后跳转的地址 传入的不能是网址和是方法请求 且该方法必须是post请求
  10. .successForwardUrl("/tomain");
  11. //授权认证
  12. http.authorizeRequests()
  13. //放行login页面 没有权限下 只能有这个页面被访问
  14. .antMatchers("/login.html").permitAll()
  15. //所以请求都要被验证
  16. .anyRequest().authenticated();
  17. //关闭csrf才能正常被访问
  18. http.csrf().disable();
  19. }

需要一个UserDetailsService 的实现类 里面定义登录名密码

  1. @Service
  2. public class UserServiceImpl implements UserDetailsService {
  3. @Autowired
  4. private PasswordEncoder passwordEncoder;
  5. @Override
  6. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  7. if(!username.equals("bb")){
  8. throw new RuntimeException("用户名不存在");
  9. }
  10. String password=passwordEncoder.encode("123");
  11. return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
  12. }
  13. }

首先说一下他的流程

SpringSecruity 会根据前端传过来的用户名 从数据库查询对应加密过的密码

然后再进行解码 与前端查询的密码进行比较 如果相等 则通过

这里为了简化 就不弄数据库了 要明白 password是加密过的 所以还需要用到一个接口实现类

就是 PasswordEncoder是接口 官方推荐用他的实现类BCryptPasswordEncoder

他主要是提供一些加密解密的功能的

示例

  1. @Test
  2. void contextLoads() {
  3. PasswordEncoder pe=new BCryptPasswordEncoder();
  4. String encode = pe.encode("123");
  5. System.out.println(encode);
  6. //matches 比较方法 第一个参数为原密码 第二个为加密后的密码
  7. System.out.println(pe.matches("123", encode));
  8. }

打印

$2a$10$7eLI1RdHYzVS6OqDBNdSyu4Sm2PBLfqx3jfkVjsUr/NPhDEE1A58e
true

注入的这个类就是起这个作用的

  1. @Configuration
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Bean
  4. public PasswordEncoder getPasswordEncoder() {
  5. return new BCryptPasswordEncoder();
  6. }
  7. }

最终要返回的User对象 就是前两个参数很明了 第三个参数要传入一个权限

AuthorityUtils.commaSeparatedStringToAuthorityList("admin")

这是自定义的 除了admin 其他名字也是随意

最终用的时候与数据库里的权限统一就好了

所以如果要通过 只有用户名为bb 密码为123才能够跳转到主页面

如图
在这里插入图片描述

失败跳转

只需要多一个error页面 和两个配置

失败跳转的请求 注意是post请求 要在controller里写 这里就不上代码了
http.formLogin().failureForwardUrl("/toerror");

错误页面也是要有权限访问的
http.authorizeRequests().antMatchers("/error.html").permitAll()

前后端分离的问题

对于前后端分离 直接传请求是不行的 需要具体的网址

只需要两个接口实现类就能完成了

AuthenticationSuccessHandlerAuthenticationFailureHandler

上代码

  1. //成功跳转 传具体的url就行了
  2. public class MySuccessHandle implements AuthenticationSuccessHandler {
  3. private String url;
  4. public MySuccessHandle(String url) {
  5. this.url = url;
  6. }
  7. @Override
  8. public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
  9. User user = (User) authentication.getPrincipal();
  10. response.sendRedirect(url);
  11. }
  12. }
  13. //失败跳转
  14. public class MyFailureHandle implements AuthenticationFailureHandler {
  15. private String url;
  16. public MyFailureHandle(String url) {
  17. this.url = url;
  18. }
  19. @Override
  20. public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
  21. response.sendRedirect(url);
  22. //打印下错误信息
  23. System.out.println(e.getMessage());
  24. }
  25. }

在前面的表单提交后面加 直接用这两个实现类就可以了 当然自动注入更好些

  1. //成功跳转的页面
  2. .successHandler(new MySuccessHandle("/main.html"))
  3. //失败跳转的页面
  4. .failureHandler(new MyFailureHandle("/error.html"));

未完待续…

发表评论

表情:
评论列表 (有 0 条评论,206人围观)

还没有评论,来说两句吧...

相关阅读