SpringSecurity入门

一、Spring Security介绍


        Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统中的一员,因此它伴随着整个Spring生态系统不断修正、升级,在spring boot项目中加入springsecurity更是十分简单,使用Spring Security 减少了为企业系统安全控制编写大量重复代码的工作。

二、快速入门

1、创建SpringBoot项目

1、依赖:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

2、配置文件:

server.port=8080
spring.application.name=spring-security

3、启动类:

@SpringBootApplication
public class AuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class,args);
    }
}

4、controller:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

    @RequestMapping("/success")
    public String success(){
        return "success";
    }

    @RequestMapping("/fail")
    public String fail(){
        return "fail";
    }
}

2、测试

地址:localhost:8080/hello

初始用户:user ,密码:控制台输出。 

三、认证

1、登录校验流程

​ SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器。

  1. UsernamePasswordAuthenticationFilter:负责处理我们在登陆页面填写了用户名密码后的登陆请求。入门案例的认证工作主要有它负责。
  2. ExceptionTranslationFilter:处理过滤器链中抛出的任何AccessDeniedException和AuthenticationException。
  3. FilterSecurityInterceptor:负责权限校验的过滤器。

2、认证流程

  1. Authentication接口: 它的实现类,表示当前访问系统的用户,封装了用户相关信息。
  2. AuthenticationManager接口:定义了认证Authentication的方法
  3. UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法。
  4. UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回。然后将这些信息封装到Authentication对象中。

3、自定义认证方式

所以根据流程图可知我们只需要实现UserDetailsService接口,就可以实现我们自己的认证

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>().eq(User::getName, username);
        User user = userMapper.selectOne(queryWrapper);
        //if(null == user){
        if(Objects.isNull(user)){
            throw new RuntimeException("用户名或密码错误");
        }
        LoginUser loginUser = new LoginUser(user);
        //TODO:查询用户权限

        //继承UserDetails类
        return loginUser;
    }
}

security配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    /**
    *加密解密
    */
    @Bean
    public PasswordEncoder passwordEncoder(){
        //加密器的实现器
        //return new BCryptPasswordEncoder(10);
        //明文密码
        return NoOpPasswordEncoder.getInstance();
    }

    /**
     * 登录时需要调用AuthenticationManager.authenticate执行一次校验
     *
     * @param config
     * @return
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    /**
     * 放行
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 禁用basic明文验证
                //.httpBasic().disable()
                // 前后端分离架构不需要csrf保护
                .csrf().disable()
                // 禁用默认登录页
                //.formLogin().disable()
                // 禁用默认登出页
                //.logout().disable()
                // 设置异常的EntryPoint,如果不设置,默认使用Http403ForbiddenEntryPoint
                //.exceptionHandling(exceptions -> exceptions.authenticationEntryPoint(invalidAuthenticationEntryPoint))
                // 前后端分离是无状态的,不需要session了,直接禁用。
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests
                        // 允许所有OPTIONS请求
                        //.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        // 允许直接访问授权登录接口
                        .requestMatchers(HttpMethod.POST, "/user/login").permitAll()
                        // 允许 SpringMVC 的默认错误地址匿名访问
                        //.requestMatchers("/error").permitAll()
                        // 其他所有接口必须有Authority信息,Authority在登录成功后的UserDetailsImpl对象中默认设置“ROLE_USER”
                        //.requestMatchers("/**").hasAnyAuthority("ROLE_USER")
                        // 允许任意请求被已登录用户访问,不检查Authority
                        .anyRequest().authenticated())
                //.authenticationProvider(authenticationProvider())
                // 加我们自定义的过滤器,替代UsernamePasswordAuthenticationFilter
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

此时就可以使用数据库中的用户名和密码进行登录校验

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值