Spring security 学习笔记(一)简单的Authentication认证

环境:IDEA Mysql JPA Spring Boot 2.X

1.准备工作

在IDEA新建一个Springboot 引入
spring-boot-starter-data-jpa
spring-boot-starter-web
spring-boot-starter-security
spring-boot-devtools (开发时调试用)
mysql-connector-java
lombok
spring-boot-starter-test

  1. 写一个系统用户实体 实现 UserDetails 接口
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class SysUser implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String realName;
    @Column(unique = true)
    private String username;
    private String password;

    public SysUser(String realName, String username, String password) {
        this.realName = realName;
        this.username = username;
        this.password = password;
    }


    /**
     * 获取用户权限信息
     *
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    /**
     * 是否过期
     *
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    /**
     * 是否被锁定
     *
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    /**
     * 密码是否过期
     *
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * 石头弃用
     *
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}
  1. 编写配置类如下
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
}
  1. 编写Repository
@Repository
public interface SysUserRepository extends JpaRepository<SysUser, Long> {
    Optional<SysUser> findByUsername(String username);
}
  1. 编写一个简单的测试类
@RestController
public class IndexController {
    @GetMapping("/")
    public String hello() {
        return "Hello Spring World";
    }
  1. 开干!第一种:在WebSecurityConfig配置类中 下面的密码加密也要
    /**
     * ====================================================
     * 自定义UserDetailService
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new CustomUserDetailsService(sysUserRepository));
    }
      /**
     * 使用BCrypt座位密码编码加密算法
     * 
     * @return
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
  1. 测试:编写一个bean加入一个用户
    @Bean
    CommandLineRunner createUser(SysUserRepository sysUserRepository, PasswordEncoder passwordEncoder) {
        return args -> {
            SysUser user = new SysUser("test", "Agitator", passwordEncoder.encode("123"));
           sysUserRepository.save(user);
        };
    }
  1. 访问localhost:8080 进行测试 自己感受
  2. 第二种:自定义authenticationProvider 编写一个类
/**
 * 自定义认证提供程序
 */
public class CustomAuthenticationProvider implements AuthenticationProvider {
    SysUserRepository sysUserRepository;
    PasswordEncoder passwordEncoder;

    public CustomAuthenticationProvider(SysUserRepository sysUserRepository, PasswordEncoder passwordEncoder) {
        this.sysUserRepository = sysUserRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String usernameFormRequest = authentication.getName();
//        获取凭证
        String passwordFormPassword = authentication.getCredentials().toString();
        Optional<SysUser> sysUserOptional = sysUserRepository.findByUsername(usernameFormRequest);
        SysUser sysUser = sysUserOptional.orElseThrow(() -> new UsernameNotFoundException("username not found"));
//        校验权限和凭证
        if (passwordEncoder.matches(passwordFormPassword, sysUser.getPassword())
                && sysUser.isAccountNonExpired()
                && sysUser.isAccountNonLocked()
                && sysUser.isCredentialsNonExpired()
                && sysUser.isEnabled()) {
            return new UsernamePasswordAuthenticationToken(sysUser.getUsername(), sysUser.getPassword(), sysUser.getAuthorities());
        } else {
//          抛出凭证异常
            throw new BadCredentialsException("Bad Credentials");
        }
    }

    /**
     * 审明当前自定义的AuthenticationProvider 认证提供者 能处理的 Authentication 认证类型为 UsernamePasswordAuthenticationToken
     *
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
}

  1. 在web配置类中注册
 /**
     * ======================================================
     * 自定义 AuthenticationProvider
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new CustomAuthenticationProvider(sysUserRepository, passwordEncoder()));
    }
  1. 第几种我忘了:前后端分离常用 Http基础认证 在上面其中一种的基础上 添加这个代码
    /**
     * 基于Http认证 重要!!!!!!! 前后端分离好用!!!
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated() // 所有请求在认证后才能访问
                .and()
                // 设置登录方式为HttpBasic 入口为 authenticationEntryPoint
                .httpBasic().authenticationEntryPoint(authenticationEntryPoint());
    }

    /**
     * http认证需要
     *
     * @return
     */
    @Bean
    AuthenticationEntryPoint authenticationEntryPoint() {
        // BasicAuthenticationEntryPoint 将认证信息放在头部,当认证未通过时放回401
        BasicAuthenticationEntryPoint authenticationEntryPoint = new BasicAuthenticationEntryPoint();
        authenticationEntryPoint.setRealmName("test");
        return authenticationEntryPoint;
    }
  1. http认证测试方法:postman 或者 apipost

    • 在postman里面找到Authorization便签
    • 使用Basic 验证方法
    • 笔者用的是apiPost

认证成功:响应码为200

响应码为200

认证失败:响应码为401

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值