spring-security使用-自定义数据源(二)
1.Spring-Security系列导航2.spring-security使用-登录(一)
3.spring-security使用-自定义数据源(二)
4.spring-security使用-更友好的方式扩展登录AuthenticationProvider(三)5.spring-security使用-获得当前用户信息(四)6.spring-security使用-同一个账号只允许登录一次(五)7.spring-security使用-session共享(六)8.spring-security使用-安全防护HttpFirewall(七)9.spring-security使用-权限控制(八)10.spring-security源码-初始化(九)11.spring-security源码-如何初始化SecurityFilterChain到Servlet12.spring-security源码-FilterChainProxy13.spring-security源码-Filter之WebAsyncManagerIntegrationFilter(十)14.Spring-security源码-Filter之SecurityContextPersistenceFilter(十一)15.Spring-security源码-Filter之HeaderWriterFilter(十二)16.Spring-security源码-Filter之LogoutFilter(十三)17.Spring-security源码-Filter之UsernamePasswordAuthenticationFilter(十四)18.Spring-security源码-Filter之ConcurrentSessionFilter(十五)19.Spring-security源码-Filter之SessionManagementFilter(十六)20.Spring-security源码-Filter之RememberMeAuthenticationFilter(十七)21.Spring-security源码-Filter之ExceptionTranslationFilter(十八)22.Spring-security源码-Filter之FilterSecurityInterceptor(十九)23.Spring-security源码-注解权限原理(二十)24.Spring-security源码-注解权限原理之MethodSecurityInterceptor(二十一)25.Spring-Security基于源码扩展-一套系统多套登录逻辑(二十二)26.Spring-Security基于源码扩展-自定义登录(二十三)27.Spring-Security基于源码扩展-自定义认证失败返回(二十四)28.Spring-Security基于源码扩展-自定义授权注解(二十五)部分源码
1.前面一demo的配置是基于内存数据源配置,但是再实际应用中我们都是查库
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { /** * inMemoryAuthentication 开启在内存中定义用户 * 多个用户通过and隔开 */ auth.inMemoryAuthentication() .withUser("liqiang").password("liqiang").roles("admin") .and() .withUser("admin").password("admin").roles("admin"); }
2.查看具体方法org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder#inMemoryAuthentication
public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception { return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer()); }
private <C extends UserDetailsAwareConfigurer<AuthenticationManagerBuilder, ? extends UserDetailsService>> C apply(C configurer) throws Exception { //这里实际拿到对应的Configer的的UserDetailsService this.defaultUserDetailsService = configurer.getUserDetailsService(); //这里先不管 return (UserDetailsAwareConfigurer)super.apply(configurer); }
3.查看UserDetailsService接口定义
public interface UserDetailsService { //根据用户名查询用户信息 UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; }
4.UserDetails接口定义
public class UserDetails { /** * 用户的权限信息 * @return */ Collection<? extends GrantedAuthority> getAuthorities(); /** * 用户密码 * @return */ String getPassword(); /*** * 用户名 * @return */ String getUsername(); /** *表示帐号是否未过期 * @return */ boolean isAccountNonExpired(); /** *表示帐号是否未锁定 * @return */ boolean isAccountNonLocked(); /** * 表示登录凭据是否未过期 * @return */ boolean isCredentialsNonExpired(); /** * 是否启用 * @return */ boolean isEnabled(); }
自定义UserDetailsService
1.先自定义封装查询用户信息的dto
public class UserInfoDto implements UserDetails { private List<?extends GrantedAuthority> authorities; private String password; private String username; public void setAuthorities(List<? extends GrantedAuthority> authorities) { this.authorities = authorities; } public void setPassword(String password) { this.password = password; } public void setUsername(String username) { this.username = username; } /** * 用户的权限信息 * @return */ @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } /** * 用户密码 * @return */ @Override public String getPassword() { return password; } /*** * 用户名 * @return */ @Override public String getUsername() { return username; } /** *表示帐号是否未过期 * @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; } }
2.实现自定义UserDetailService
@Service public class UserService implements UserDetailsService { /** * 根据用户名查询用户信息 * @param s * @return * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { //模拟查询db System.out.println("模拟查询db"); //将db查询结果封装返回 UserInfoDto userInfoDto=new UserInfoDto(); userInfoDto.setUsername(s); userInfoDto.setPassword("22222");
//权限标识 userInfoDto.setAuthorities(null); return userInfoDto; } }
3.设置自定义的userServuce
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //设置自定义的userDetailService auth.userDetailsService(userService); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!