springsecurity学习流程

1.1 入门程序

  1. 因为是安全框架,所以先简单写一个登录的html,然后用controller去接收他。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login" method="post">
        <!-- 这个必须叫username和password,否则会报错 -->
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>
package com.jerry.springsecuritydemo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 登录
 */
@RestController
public class LoginController {
   


    @RequestMapping("/login")
    public String login() {
   
        System.out.println("执行了登陆方法");
        return "redirect:main:html";
    }
}
  1. 此时我们访问localhost:8080/login.html会跳到localhost:8080/login中,这是springsecurity带给我们的一个界面,默认的用户名是user,密码是启动时给的。如下:

在这里插入图片描述

登录之后才会到我们自己的登录界面。
这就是最简单的案例。

1.2 自定义登陆逻辑

现在我们的登陆账号和密码都是固定死的,每次由springsecurity给我们生成,如果我们想要使用自己的数据库中的数据的话,需要以下几点:

  1. 实现UserDetailsService接口并注入到容器中
  2. 通过重写loadUserByUsername即可

loadUserByUsername方法返回了一个UserDetails接口,从接口中可以看到它有获取用户名密码权限是否可用等方法。

通过查看UserDetails的结构可以看到他有一个User类,我们只需要返回这个实现类即可。

因为在数据库中的密码都是加密过的,所以我们需要一个PasswordEncoder来进行密码的编码和验证。

由于PasswordEncoder也是一个接口,并且方法中的注释:

/**
* Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
* greater hash combined with an 8-byte or greater randomly generated salt.
*/

推荐了我们使用什么方法,我们可以采用他的子类BCryptPasswordEncoder

具体实现:

  1. ​ SpringSecurity要求Spring容器中必须有一个PasswordEncoder的实例,所以先注入
// 配置类,注入PasswordEncoder
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig {
   

    /**
     * SpringSecurity要求Spring容器中必须有一个PasswordEncoder的实例
     * @return
     */
    @Bean
    public PasswordEncoder getPasswordEncoder() {
   
        return new BCryptPasswordEncoder();
    }

}
  1. 实现UserDetailsService
// 注意@Service注解,或者其余的注解。总之要注入到spring容器中
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
   

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
   
        // 判断用户名是否存在,不存在要抛出异常UsernameNotFoundException
        if (!"admin".equals(username)) {
   
            throw new UsernameNotFoundException("用户名不存在");
        }
        // 把查询出来的密码(数据库加密过的密码)进行解析,或者直接把密码放入构造方法
        String password = passwordEncoder.encode("mypassword");
        System.out.println("password:" + password);
        return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));
    }
}

接下来,我们在用原来的user|显示的密码已经进不去了,反而admin|mypassword可以进去。

到此我们可以在自定义账号和密码了。

1.3 自定义登陆界面

一般都不会采用springsecurity的自带的界面。

修改登陆界面需要:

  1. 使用一个配置去去继承WebSecurityConfigurerAdapter重写configure方法
  2. 修改登陆界面,登录跳转界面,还有登录路径
  3. 关闭csrf
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   

    @Override
    protected void configure(HttpSecurity http) throws Exception {
   
        // 表单提交
        http.formLogin()
                .loginProcessingUrl("/login") // 发现/login时认为登录,这个地方必须和login.html提交的那个action一样
                .loginPage("/login.html") // 登录的界面
                .successForwardUrl("/toMain");
        // 其实上面定义了登录界面和成功之后跳转到哪,思考之后发现login方法已经没有用了
        // 判断已经有UserDetailsServiceImpl来代替了
        
        
        http.authorizeRequests() // 类似拦截器
                .antMatchers("/login.html").permitAll() // 放行login.html
                .anyRequest() // 任何请求
                .authenticated(); // 必须都被授权
		// 关闭csrf
        http.csrf()
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值