导入依赖框架
 
         web 框架(spring-boot-starter-web)
 
 
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
 
         springSecurity 框架(spring-boot-starter-security)
 
 
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
 
 
导入框架之后、当前应用已经具备验证功能
 
-  用户名默认为user、密码为启动窗口打印信息 
-  默认登陆页(存在问题、每次需要记录登录密码) 
-   配置文件配置固定用户名、密码 
 
自定义功能实现(用户信息从数据库获取)
 
        方式一: 
 
 -  导入数据源依赖 mysql\mybatis,配置数据源信息  <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency>
  
-  直接配置查询 sql (select username,password from s_usr where username = ?)package com.bu.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;import javax.sql.DataSource;/*** @author haizhuangbu* @date 2024/5/15 16:35* @mark WebSecurityConfigImpl*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication()// 配置数据源.dataSource(dataSource)// 查询sql.usersByUsernameQuery("select username,password,'Y' enabled from s_usr where username = ?").authoritiesByUsernameQuery("select username,authority\n" +"from authorizes where username = ?");}// 不进行解密、直接对比@Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}}
 
-  此时用户信息就是去数据库查询的 (用户信息表 创建包含用户密码关键字段即可)create table s_usr
(user_id     varchar(36) not nullprimary key,username    varchar(36) null,password    varchar(36) null,create_time datetime    null,modify_time datetime    null,enable      char(2)     null comment 'Y 生效 N 失效'
);create table authorizes
(username  varchar(36),authority varchar(36)
);insert into s_usr
values ('1', 'admin', 'admin', now(), now(), 'Y');
 
 
        方式二:
 
 -  导入数据源配置信息同方式一相同           
-  重写springSecurity 的几个组件- UserDetailsService 用户信息查询接口(内部具体编写查询逻辑 ) package com.bu.config;import com.bu.sys.user.dao.UserDetailsDao;
import com.bu.sys.user.dto.SUsrDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;/*** @author haizhuangbu* @date 2024/5/15 16:22* @mark AuthUserServiceImpl*/
@Component
public class AuthUserServiceImpl implements UserDetailsService {@Autowiredprivate UserDetailsDao userDetailsDao;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {SUsrDto sUsrDto = userDetailsDao.findSUsrByUsername(username);return sUsrDto;}
}package com.bu.sys.user.dao;import com.bu.sys.user.dto.SUsrDto;
import org.apache.ibatis.annotations.Select;/*** @author haizhuangbu* @date 2024/5/15 17:15* @mark UserDetailsDao*/
public interface UserDetailsDao {@Select("select * from s_usr where username = #{username}")SUsrDto findSUsrByUsername(String username);}
 
- PasswordEncoder 加解密工具 // 不进行解密、直接对比@Beanpublic PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}
 
- UserDetail 用户信息 package com.bu.sys.user.dto;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;/*** @author haizhuangbu* @date 2024/5/15 17:16* @mark SUsrDto*/
public class SUsrDto implements UserDetails {private String username;private String password;public String getUsername() {return username;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}public void setUsername(String username) {this.username = username;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
 
-  AuthenticationProvider 验证流程 package com.bu.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;/*** @author haizhuangbu* @date 2024/5/15 17:20* @mark UserAutorizedServiceImpl*/
@Component
public class UserAuthorizedServiceImpl implements AuthenticationProvider {@Autowiredprivate UserDetailsService userDetailsService;@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {// 查询用户信息UserDetails userDetails = userDetailsService.loadUserByUsername(authentication.getName());if (userDetails == null) {throw new UsernameNotFoundException("用户信息不存在");}if (!passwordEncoder.matches(userDetails.getPassword(), (String) authentication.getCredentials())) {throw new UsernameNotFoundException("密码不正确");}return new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());}@Overridepublic boolean supports(Class<?> aClass) {return true;}
}
 
 
-   验证组件交给springSecurity (同数据源方式类似)package com.bu.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;import javax.sql.DataSource;/*** @author haizhuangbu* @date 2024/5/15 16:35* @mark WebSecurityConfigImpl*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {@Autowiredprivate UserAuthorizedServiceImpl userAuthorizedService;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(userAuthorizedService);}}
 
 
配置其他信息(成功跳转、失败跳转....)
 
   // 非页面列表页可以无权限访问外、其他都需要验证@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()// permitAll 放行路径.antMatchers("/login", "/blogs/listAllBlogs", "/blogs/listBloggerInfo", "/theme/listAll").permitAll().anyRequest().authenticated().and().formLogin() // 默认 login 登陆路径.failureHandler(failLoginHandler)// 成功处理逻辑
//                .defaultSuccessUrl("/success")
//                .failureUrl("/error").and().addFilterAfter(tokenFilter, BasicAuthenticationFilter.class);http.csrf().disable();http.cors().disable();}
 
详细配置思维导图
 
