1.加入SpringSecurity依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.7.8</version> </dependency>
加入依赖后security会自动开启认证,访问项目的接口会自动转到/login页面
2.自定义认证
实现UserDetailsService接口
自定义逻辑根据用户名构建UserDetails类,初始化用户密码、权限。
如果用户信息存在数据库中,数据库中要存储加密后的密码,即调用PasswordEncoder.encode加密后存到数据库中,因为用户登录后密码会自动调用PasswordEncoder.matches验证输入密码和数据库中存储的加密后的密码。
@Service public class SpringSecurityUserServiceImpl implements UserDetailsService { @Resource private UserFeignClient userFeignClient; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { ResponseResult<LoginUser> loginUser = userFeignClient.findByUsername(username); if (loginUser == null || loginUser.getData() == null) { throw new UsernameNotFoundException("user not found"); } //TODO 用户权限 List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(); GrantedAuthority grantedAuthority = () -> null; grantedAuthorityList.add(grantedAuthority); return new User(username,loginUser.getData().getPassword(),grantedAuthorityList); } }
实现PasswordEncoder接口
可以自定义PasswordEncoder实现类,也可以用SpringSecurity默认提供的类,如果用默认提供的类注意在配置类中注入该类.
3.配置类配置
配置认证策略
/** * springSecurity全局配置 * @author zp */ @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http //配置需要认证的接口路径 .authorizeHttpRequests(auth -> auth //白名单 .antMatchers("/userInfo/findByUsername").permitAll() //其余所有接口都需要认证 .anyRequest().authenticated() ) // .formLogin( form -> form // .loginPage("/login") // 自定义登录页面 // .loginProcessingUrl("/login") // 处理登录请求的URL // .defaultSuccessUrl("/welcome", true) // 登录成功后的默认跳转URL // .failureUrl("/login?error") // 登录失败后的URL // .permitAll() // 允许任何人访问登录页面 // ) .formLogin(withDefaults()) .logout(withDefaults()) //远程api访问配置,即如果此项开启通过api访问会弹出登录框,不开启会返回登录页面 .httpBasic(withDefaults()) //对于所有非get方法,默认开启csrf保护,都必须在header中加上csrftoken,就算配置了白名单也没用 .csrf(withDefaults()) //记住我,生成一个包含用户身份信息的cookie,并在用户浏览器上保存,并且默认使用一个密匙来加密 .rememberMe(withDefaults()); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }