SpringSecurity

springsecurity.jpg

1. 简介

Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。也就是一个权限框架。

2. 核心功能

  • 用户认证(Authentication):检验用户名和密码的过程,判断用户是否已经登陆。
  • 用户授权(Authorization):判断用户是否有权限访问。

3. 基本原理

本质上是一个过滤器(filter)。

  • 如果基于session,那么会对cookie的SessionId进行解析。根据SessionId在服务器上进行查找,判断是否符合要求。
  • 如果基于token,则会解析token,然后将请求加入到springsecurity管理的权限中去。

4.springboot项目中引入依赖


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

5. 配置登陆名和密码

  • 默认配置:拦截后会自动跳转默认的登陆页面,用户名为user,密码为控制台显示的一串字符。
  • 配置文件配置:application.properties
spring.security.user.name=xxx
spring.security.user.password=xxx
  • 内存中配置

    • 自定义类继承WebSecurityConfigurerAdapter
    • 重写configure(AuthenticationManagerBuilder auth)

      • 注意:密码必须加密,不加密会无法通过校验,控制台报错:Encode Password does not look like BCrypt. 下面的BCryptPasswordEncoder也需要加载到容器中。

MyWebSecurityConfig

public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        内存中虚拟用户
        String password = bCryptPasswordEncoder.encode("123456");
        System.out.println(password);
        auth.inMemoryAuthentication().withUser("hello").password(password).roles("admin");
    }

    @Bean
    BCryptPasswordEncoder getBCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
  • 自定义实现(常用):数据库中查询用户名和密码

    • 自定义类 MyUserDetailsService 实现 UserDetailsService 接口。
    • 重写 loadUserByUsername (String s) 方法。
    • 数据库查询用户信息。
    • return user。

MyWebSecurityConfig


@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    UserDetailsService myUserDeetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //需要一个UserDetailsService的实现类
        auth.userDetailsService(myUserDeetailsService);
    }

    @Bean
    BCryptPasswordEncoder getBCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

MyUserDetailsService


@Service("myUserDeetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    @Qualifier("userService")
    UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        List auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin");

        QueryWrapper qw = new QueryWrapper();

        qw.eq("username", username);

        vip.zhguo.springsecurity.pojo.User one = userService.getOne(qw);

//        System.out.println(one.toString());

        if (one == null)
            throw new UsernameNotFoundException("用户名不存在");

        return new User(one.getUsername(), bCryptPasswordEncoder.encode(one.getPassword()), auth);
    }
}

6. 修改默认登陆界面

MyWebSecurityConfig中重写configure(HttpSecurity http)

    @Override
protected void configure(HttpSecurity http)throws Exception{
        http.formLogin().loginPage("/login.html")   //设置登陆页面
        .loginProcessingUrl("/login")   //设置登陆页面提交登陆请求的地址
        .defaultSuccessUrl("/index")    //登陆成功后跳转的路径
        .permitAll()    //放行
        .and()
        .authorizeRequests()
        .antMatchers("/","/login.html") //设置的页面不会拦截
        .permitAll()
        .and()
        .csrf().disable()     //关闭csrf保护
        .authorizeRequests()
        .antMatchers("/admin/**").hasRole("admin")  //是否具有admin角色
        .antMatchers("/admin/**").hasAnyRole("admin","root")    //admin和root角色任意一个就行
        .antMatchers("/admin/**").hasAuthority("admin")     //是否具有admin权限
        .antMatchers("/admin/**").hasAnyAuthority("admin","root")//admin和root权限任意一个就行
        .anyRequest().authenticated();   //其他都需要拦截认证。
        }

注意:.authorizeRequests().antMatchers("/admin/**") 搭配使用,role默认会加ROLE_前缀,commaSeparatedStringToAuthorityList就需要加前缀


@Service("myUserDeetailsService")
public class MyUserDeetailsService implements UserDetailsService {

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    @Qualifier("userService")
    UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        List auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin");

        QueryWrapper qw = new QueryWrapper();

        qw.eq("username", username);

        vip.zhguo.springsecurity.pojo.User one = userService.getOne(qw);

//        System.out.println(one.toString());

        if (one == null)
            throw new UsernameNotFoundException("用户名不存在");

        return new User(one.getUsername(), bCryptPasswordEncoder.encode(one.getPassword()), auth);
    }
}

后面还有基于注解的,实际不便于维护,就过了。

最后修改:2022 年 07 月 17 日
如果觉得我的文章对你有用,请随意赞赏