Spring Security打卡第一天

Spring Security第一天学习

(跟随江南一点雨大佬的脚步一点点学习)

我为什么要学Spring Security:
  • 随着互联网公司的网络安全意识逐步增加,对于安全方面越来越重视,并且由于SpringBoot和SpringCloud越来越普及,所以我觉得对我而言肯定有必要去了解学习下Security
废话不多说开整:

1.利用Idea快速创建一个SpringBoot的工程兵器添加web和Security的依赖(Web里面记得也勾选上Web的依赖)

2.写一个简单的方法测试Security

@RestController
@RequestMapping("/")
public class SecurityController {

    @GetMapping("/demo")
    public String demo() {
        return "hello";
    }
}

3.启动Boot,这个时候我们看日志会发现在我们并没有写相关于Security的代码但是Security却已近为我们接口全局都做了保护

/*在控制台中找到可以看到*/
Using generated security password: 16640c87-fb51-4bf9-bf18-5bfcb83a42ac

为啥会这么说呢?我们查找下UserDetailsServiceAutoConfiguration这个类的getOrDeducePassword方法就会发现底下的这个判断他返回的结果为true,所以它将日志信息写入到了我们的控制台中

private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
    String password = user.getPassword();
    if (user.isPasswordGenerated()) { /*结果为true*/
          logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));
     }
    if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {
          return password;
     }
      return NOOP_PASSWORD_PREFIX + password;
}

4.那么我们的密码是如何生成的呢?我们默认的用户名是什么呢?
我们点入到SecurityPropertie这个类中去,通过上一副图片我们可以知道我们密码的生成是调用了SecurityProperties中的User这个静态的类里面的UUID.randomUUID().toString()生成随机密码

/**
*Default user name.
*通过这段我们可以明白原来默认用户名是user
*/
private String name = "user";

/**
*Granted roles for the default user name.
*生成随机的UUID字符串作为密码
*/            
private String password = UUID.randomUUID().toString(); 

5.接下来用我们知道的用户名和密码进行登陆下
在登陆的过程中我们会发现地址栏出现了404的错误,这个时候我们仔细观察下地址栏上的路径原来地址栏上的路径变成了localhost:8080,这个时候Security对我们的登陆鉴权已经完成了,所以我们直接将路径修改为localhost:8080/demo就能在页面上看见我们的hello,想直接跳转这个时候我们可以借助重定向跳转到我们的hello页面,不需要手动输入

配置用户名密码登陆

我们可以想下由于Security的密码是随机生成的那么每次在重启项目的时候我们是不是会生成一个随机的密码?这样可不太好,所以如果我们想自定义用户名和密码我们可以覆盖掉SecurityProperties中读取的配置文件

#为啥我们定义的名字要是以spring.security开头的呢?我们看这个类
@ConfigurationProperties(prefix = "spring.security")
public class SecurityProperties {
}
#@ConfigurationProperties这个注解我们很熟悉吧,这个注解的作用是Spring提供给我们读取配置文件的一种方式,prefix表示我们读取配置文件的时候读取的配置的头前缀是啥,所以我们想要去读取自己自定的的配置,只需要去在我们新的配置中去覆盖掉这类就好了

#配置Security的用户名和密码
spring.security.user.name=GGYD
spring.security.user.password=DDYG

这边其实我们也可以小小的看下Security对读取的配置文件的密码的判断

public void setPassword(String password) {
    if (!StringUtils.hasLength(password)) { //判断传入的是字符串且长度不为空
            return;
      }
      this.passwordGenerated = false;
      this.password = password;
}
/*
 *@return {@code true} if the {@code String} is not {@code null} and has length 
 *这个说方法它已经告诉了我们如果这是个字符串且长度不为空那么返回的结果为true
 */
Stringutils.hasLength(String str);


/*同时在setPassword中也设置了passwordGenerated = false,当这个属性设置为false时我们的控制台上就不会打印默认的密码了*/
使用Java代码的方式配置用户
@Configuration
public class SecurityBeanConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public PasswordEncoder passwordEncoder(){
     return NoOpPasswordEncoder.getInstance();
}


  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    /*通过这段代码我们应该能明白了,如果我们有多个用户登陆那么我们可以选择用and()来进行连接*/
    auth.inMemoryAuthentication().withUser("DYGG").password("123").roles("admin")
                            .and().withUser("GGYD").password("456").roles("admin");
}


/***
  * 配置静态资源路径不拦截
  * @param web
  * @throws Exception
  */
  @Override
  public void configure(WebSecurity web) throws Exception {
    String[] str = {"/js/**", "/css/**","/images/**"};
     web.ignoring().mvcMatchers(str);
}

  @Override
  protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")
                .permitAll() //表示当前登陆相关的页面/接口不要被拦截
                .and() //结束当前标签,上下文回到HttpSecurity,开启新的一轮的配置
                .csrf()
                .disable();
    }
}

如果大家想看写的更好的Security可以关注下江南一点雨的公众号,这基本都是按照大佬的来写的,我单纯的只是为了给自己一个学习的记录罢了

原文地址:https://www.cnblogs.com/Lingzsj/p/14619788.html