当前位置: 首页 > news >正文

漳州企业网站建设erp管理系统介绍

漳州企业网站建设,erp管理系统介绍,wordpress 国人主题,惠州网站设计方案前言 《Spring Security学习#xff08;五#xff09;——账号密码的存取》一文已经能满足一般应用的情况。但实际商业应用也会存在如下的情况#xff1a;用户提交的账号密码#xff0c;能在本地的保存的账号密码匹配上#xff0c;或者能在远端服务认证中匹配上#xff…前言 《Spring Security学习五——账号密码的存取》一文已经能满足一般应用的情况。但实际商业应用也会存在如下的情况用户提交的账号密码能在本地的保存的账号密码匹配上或者能在远端服务认证中匹配上就算认证通过。这种通常类似于单点登录或者认证中心之类的。本文不去探索这种架构只是单纯讨论如果存在两种认证规则下如何处理。 多种认证方式使用Spring Security时有好几种处理方式。根据不同的情况架构师考虑不同的解决方案。本文先从比较简单的方案说起。 假设能匹配数据库保存的账号密码或者能匹配内存中保存的账号密码两者之一就算认证通过。附加条件 这两种认证方式是通过同一方式提交用户密码这两种认证方式是一条链式的处理方式。比如先判断第一种方式是否通过认证不通过则判断第二种。 上述情况我们考虑使用多个provider去处理。 架构 前面的文章讲过ProviderManager是AuthenticationManager的实现。其架构图如下 在《Spring Security学习五——账号密码的存取》 中我们说过DaoAuthenticationProvider撬动UserDetailsService和PasswordEncoder的“杠杆”。DaoAuthenticationProvider则是AuthenticationProvider的默认实现。Spring Security通过AuthenticationProvider调用获取UserDetails然后进行匹配最后返回UsernamePasswordAuthenticationTokenAuthentication接口的具体。 对于Spring Security的当存在多个AuthenticationProvider的实现时用户提交的账号密码满足其中任意一个AuthenticationProvider返回正确的Authentication即可。 自定义AuthenticationProvider 我们做个简单的自定义AuthenticationProvider。自定义MyProvider类 Data public class MyProvider extends AbstractUserDetailsAuthenticationProvider{private UserDetailsServiceImpl userDetailsServiceImpl;private PasswordEncoder passwordEncoder;private static final String USER_NOT_FOUND_PASSWORD userNotFoundPassword;private volatile String userNotFoundEncodedPassword;Overrideprotected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)throws AuthenticationException {prepareTimingAttackProtection();try {UserDetails loadedUser userDetailsServiceImpl.loadUserByMemory(username);if (loadedUser null) {throw new InternalAuthenticationServiceException(UserDetailsService returned null, which is an interface contract violation);}return loadedUser;}catch (UsernameNotFoundException ex) {mitigateAgainstTimingAttack(authentication);throw ex;}catch (InternalAuthenticationServiceException ex) {throw ex;}catch (Exception ex) {throw new InternalAuthenticationServiceException(ex.getMessage(), ex);}}Overrideprotected void additionalAuthenticationChecks(UserDetails userDetails,UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {if (authentication.getCredentials() null) {this.logger.debug(Failed to authenticate since no credentials provided);throw new BadCredentialsException(this.messages.getMessage(AbstractUserDetailsAuthenticationProvider.badCredentials, Bad credentials));}String presentedPassword authentication.getCredentials().toString();if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {this.logger.debug(Failed to authenticate since password does not match stored value);throw new BadCredentialsException(this.messages.getMessage(AbstractUserDetailsAuthenticationProvider.badCredentials, Bad credentials));}}private void prepareTimingAttackProtection() {if (this.userNotFoundEncodedPassword null) {this.userNotFoundEncodedPassword this.passwordEncoder.encode(USER_NOT_FOUND_PASSWORD);}}private void mitigateAgainstTimingAttack(UsernamePasswordAuthenticationToken authentication) {if (authentication.getCredentials() ! null) {String presentedPassword authentication.getCredentials().toString();this.passwordEncoder.matches(presentedPassword, this.userNotFoundEncodedPassword);}} } 自定义Provider应该实现AuthenticationProvider接口并实现authenticate方法。这里我们参考DaoAuthenticationProvider来写重写retrieveUser方法调用我们自定义的userDetailsServiceImpl的loadUserByMemory方法从内存获取。additionalAuthenticationChecks方法的作用是对提交的密码和系统中保存的密码进行匹配这里直接参考DaoAuthenticationProvider类的写法。prepareTimingAttackProtection和mitigateAgainstTimingAttack都是用来防御计时攻击的非认证必要。 在《Spring Security学习二——使用数据库保存密码》中我们定义了SysUserServiceImpl这里进行一些修改 Component public class UserDetailsServiceImpl implements UserDetailsService{Autowiredprivate SysUserService userService;private static MapString, SysUserEntity userMap;static {userMap new HashMapString, SysUserEntity();SysUserEntity sysUser new SysUserEntity();sysUser.setUsername(test);sysUser.setPassword(test###);userMap.put(test, sysUser);}Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {QueryWrapperSysUserEntity queryWrapper new QueryWrapperSysUserEntity();queryWrapper.eq(username, username);queryWrapper.last(limit 1);SysUserEntity user userService.getOne(queryWrapper);if(user null) {throw new UsernameNotFoundException(username not found);}return (new LoginUser(user));}public UserDetails loadUserByMemory(String username) throws UsernameNotFoundException {if(StrUtil.isNotEmpty(username)) {SysUserEntity user userMap.get(username);if(user null) {throw new UsernameNotFoundException(username not found);}return (new LoginUser(user));}return null;} } 首先我们增加一个loadUserByUsername方法用于读取map中保存的测试账号。另外之前当我们查询找不到对象的时候抛出了RuntimeException按照Spring Security的设计思想来说是不对的应该抛出UsernameNotFoundException让上层接住这个异常。抛出RuntimeException会直接终止后面provider的匹配不符合Spring Security的设计理念。 自定义密码加密器还是使用之前文章的版本MyPasswordEncoder为原密码后加3个# public class MyPasswordEncoder implements PasswordEncoder {Overridepublic String encode(CharSequence rawPassword) {return rawPassword ###;}Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {if (encodedPassword.equals(rawPassword ###)) {return true;}return false;} } 另外由于自定义加密方式所以数据库密码也要改一下 最后修改一下WebSecurityConfig的配置把自定义的MyProvider加进去 EnableWebSecurity public class WebSecurityConfig{Beanpublic MyPasswordEncoder PasswordEncoder() {return new MyPasswordEncoder();}Beanpublic SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize - authorize.anyRequest().authenticated()).formLogin(Customizer.withDefaults());MyProvider myProvider new MyProvider();myProvider.setPasswordEncoder(PasswordEncoder());UserDetailsServiceImpl UserDetailsServiceImpl SpringUtils.getBean(UserDetailsServiceImpl.class);myProvider.setUserDetailsServiceImpl(UserDetailsServiceImpl);http.authenticationProvider(myProvider);DaoAuthenticationProvider daoAuthenticationProvider new DaoAuthenticationProvider();daoAuthenticationProvider.setPasswordEncoder(PasswordEncoder());daoAuthenticationProvider.setUserDetailsService(UserDetailsServiceImpl);http.authenticationProvider(daoAuthenticationProvider);return http.build();} } 16行新建MyProvider17行设置自定义的加密器18-19行设置UserDetailsServiceImpl。20行加到HttpSecurity中。22行设置DaoAuthenticationProvider到HttpSecurity中。 之后我们同样是访问/hello路径然后在默认登录页分别尝试使用jake/123test/test两个账号登陆。会发现通过两种认证方式都可以登陆成功。 小结 本文使用自定义Provider的方式让用户匹配多种认证方式。这个只是最简单的方式。从系列文章的本文章开始就涉及很多需要了解Spring Security架构设计的情况读者最好还是阅读源码去理解。否则生搬硬套很难达到实际开发想要达到的目的。本文主要涉及ProviderManager、DaoAuthenticationProvider、AbstractUserDetailsAuthenticationProvider的源码。读者最好阅读一下以了解本文实现的思路。 其实还有个小疑问WebSecurityConfig似乎我们去掉DaoAuthenticationProvider的配置一样能达到同样的效果那我们的配置是不是有点多余了其实这涉及另一个概念留到下一篇文章再讲。
http://www.sczhlp.com/news/220605/

相关文章:

  • 西樵网站开发wordpress 页面 编辑器
  • 网站建设越来越便宜dw下载中文版破解
  • 网站建设一般多少做网站人
  • 设计一份包含网站建设范网站备案信息保护
  • 网站申请微信登录童装东莞网站建设技术支持
  • 网站建设免费建站免费源代码支持企业网站发布要怎么做
  • 同学录网站建设成都培训学校网站建设
  • 中堂做网站工程建设室内涂料招投标网站
  • 设计师合作网站织梦网站怎么把index.html去掉
  • 西安网站制作建设北京seo公司工作
  • 渭南做网站中国制造网建站
  • 正邦设计面试网络推广seo公司
  • 网站备案和域名备案一样吗怎样建设企业网站 用于宣传
  • 两两交换链表中的节点-leetcode
  • 10.20-10.26
  • 20232421 2025-2026-1 《网络与系统攻防技术》实验二实验报告
  • Serilog基于Seq开源框架实现日志分析
  • 网站建设售前怎么做好类似小红书网站开发费用
  • 易旅游网站建设网站首页的重要性
  • 北京大龙建设集团有限公司网站首页网络营销概念及理解
  • 个人做网站租云服务器天津做网站找谁
  • 建设摩托车官方网站企业网站建设是什么
  • 如何进行企业营销型网站建设规划dedecms 网站栏目管理
  • wordpress媒体库注册seo的中文是什么意思
  • 静态网站怎么样易安卓开发app稳定吗
  • php 如何在网站根目录创建文件夹百度引流平台
  • 网站开发中界面重庆中心城区恢复
  • 图片编辑器免费版合肥网站seo公司
  • 网站建设按年收费吗网站快速建设
  • 用dw制作学校网站教程小微企业名录