范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

SpringSecurity玩出花!两种方式DIY登录

  一般情况下,我们在使用 Spring Security 的时候,用的是 Spring Security 自带的登录方案,配置一下登录接口,配置一下登录参数,再配置一下登录回调就能用了,这种用法可以算是最佳实践了!
  但是!
  总会有一些奇奇怪怪得需求,例如想自定义登录,像 Shiro 那样自己写登录逻辑,如果要实现这一点,该怎么做?今天松哥就来和大家分享一下。
  松哥琢磨了一下,想在 Spring Security 中自定义登录逻辑,我们有两种思路,不过这两种思路底层实现其实异曲同工,我们一起来看下。  1. 化腐朽为神奇
  前面松哥和大家分享了一个 Spring Security 视频:  没见过的奇葩登录
  这个视频里主要是和大家分享了我们其实可以使用 HttpServletRequest 来完成系统的登录,这其实是 JavaEE 的规范,这种登录方式虽然冷门,但是却很好玩!
  然后松哥还和大家分享了一个视频:  SpringSecurity登录数据获取最后一讲
  这个视频其实是在讲 Spring Security 对 HttpServletRequest 登录逻辑的实现,或句话说,HttpServletRequest 中提供的那几个和登录相关的 API,Spring Security 都按照自己的实现方式对其进行了重写。
  有了这两个储备知识后,第一个 DIY Spring Security 登录的方案呼之欲出。  1.1 实践
  我们来看看具体操作。
  首先我们来创建一个 Spring Boot 工程,引入 Web 和 Security 两个依赖,如下:
  方便起见,我们在 application.properties 中配置一下默认的用户名密码:  spring.security.user.name=javaboy spring.security.user.password=123
  接下来我们提供一个 SecurityConfig,为登录接口放行:  @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {     @Override     protected void configure(HttpSecurity http) throws Exception {         http.authorizeRequests()                 .antMatchers("/login")                 .permitAll()                 .anyRequest().authenticated()                 .and()                 .csrf().disable();     } }
  登录接口就是  /login ,一会我们自定义的登录逻辑就写在这个里边,我们来看下: @RestController public class LoginController {     @PostMapping("/login")     public String login(String username, String password, HttpServletRequest req) {         try {             req.login(username, password);             return "success";         } catch (ServletException e) {             e.printStackTrace();         }         return "failed";     } }
  直接调用 HttpServletRequest#login 方法,传入用户名和密码完成登录操作。
  最后我们再提供一个测试接口,如下:  @RestController public class HelloController {     @GetMapping("/hello")     public String hello() {         return "hello security!";     } }
  just this!
  启动项目,我们首先访问  /hello  接口,会访问失败,接下来我们访问 /login 接口执行登录操作,如下:
  登录成功之后,再去访问  /hello  接口,此时就可以访问成功了。
  是不是很 Easy?登录成功后,以后的授权等操作都还是原来的写法不变。  1.2 原理分析
  上面这种登录方式的原理其实松哥一开始就介绍过了,如果大家还不熟悉,可以看看这两个视频就懂了:  没见过的奇葩登录  SpringSecurity登录数据获取最后一讲
  这里我也是稍微说两句。
  我们在 LoginController#login 方法中所获取到的 HttpServletRequest 实例其实是 HttpServlet3RequestFactory 中的一个内部类 Servlet3SecurityContextHolderAwareRequestWrapper 的对象,在这个类中,重写了 HttpServletRequest 的 login 以及 authenticate 等方法,我们先来看看 login 方法,如下:  @Override public void login(String username, String password) throws ServletException {  if (isAuthenticated()) {   throw new ServletException("Cannot perform login for "" + username + "" already authenticated as ""     + getRemoteUser() + """);  }  AuthenticationManager authManager = HttpServlet3RequestFactory.this.authenticationManager;  if (authManager == null) {   HttpServlet3RequestFactory.this.logger.debug(     "authenticationManager is null, so allowing original HttpServletRequest to handle login");   super.login(username, password);   return;  }  Authentication authentication = getAuthentication(authManager, username, password);  SecurityContextHolder.getContext().setAuthentication(authentication); }
  可以看到:  如果用户已经认证了,就抛出异常。  获取到一个 AuthenticationManager 对象。  调用 getAuthentication 方法完成登录,在该方法中,会根据用户名密码构建 UsernamePasswordAuthenticationToken 对象,然后调用 Authentication#authenticate 方法完成登录,具体代码如下:  private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)   throws ServletException {  try {   return authManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));  }  catch (AuthenticationException ex) {   SecurityContextHolder.clearContext();   throw new ServletException(ex.getMessage(), ex);  } } ❝
  该方法返回的是一个认证后的 Authentication 对象。 最后,将认证后的 Authentication 对象存入 SecurityContextHolder 中,这里的具体逻辑我就不啰嗦了,我在公众号【江南一点雨】之前的视频中已经讲过多次了。
  这就是 login 方法的执行逻辑。
  Servlet3SecurityContextHolderAwareRequestWrapper 类也重写了 HttpServletRequest#authenticate 方法,这个也是做认证的方法:  @Override public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {  AuthenticationEntryPoint entryPoint = HttpServlet3RequestFactory.this.authenticationEntryPoint;  if (entryPoint == null) {   HttpServlet3RequestFactory.this.logger.debug(     "authenticationEntryPoint is null, so allowing original HttpServletRequest to handle authenticate");   return super.authenticate(response);  }  if (isAuthenticated()) {   return true;  }  entryPoint.commence(this, response,    new AuthenticationCredentialsNotFoundException("User is not Authenticated"));  return false; }
  可以看到,这个方法用来判断用户是否已经完成认证操作,返回 true 表示用户已经完成认证,返回 false 表示用户尚未完成认证工作。  2. 源码的力量
  看了上面的原理分析,大家应该也明白了第二种方案了,就是不使用 HttpServletRequest#login 方法,我们直接调用 AuthenticationManager 进行登录验证。
  一起来看下。
  首先我们修改配置类如下:  @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {     @Override     protected void configure(HttpSecurity http) throws Exception {         http.authorizeRequests()                 .antMatchers("/login","/login2")                 .permitAll()                 .anyRequest().authenticated()                 .and()                 .csrf().disable();     }      @Override     @Bean     public AuthenticationManager authenticationManagerBean() throws Exception {         DaoAuthenticationProvider provider = new DaoAuthenticationProvider();         InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();         manager.createUser(User.withUsername("javaboy").password("{noop}123").roles("admin").build());         provider.setUserDetailsService(manager);         return new ProviderManager(provider);     } } 首先在登录放行中,添加  /login2  接口,这是我即将自定义的第二个登录接口。 提供一个 AuthenticationManager 实例,关于 AuthenticationManager 的玩法松哥在之前的 Spring Security 系列中已经多次分享过,这里就不再赘述(没看过的小伙伴公众号后台回复  ss )。创建 AuthenticationManager 实例时,还需要提供一个 DaoAuthenticationProvider,大家知道,用户密码的校验工作在这个类里边完成,并为 DaoAuthenticationProvider 配置一个 UserDetailsService 实例,该实体提供了用户数据源。
  接下来提供一个登录接口:  @RestController public class LoginController {     @Autowired     AuthenticationManager authenticationManager;     @PostMapping("/login2")     public String login2(String username, String password, HttpServletRequest req) {         try {             Authentication token = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));             SecurityContextHolder.getContext().setAuthentication(token);             return "success";         } catch (Exception e) {             e.printStackTrace();         }         return "failed";     } }
  在登录接口中,传入用户名密码等参数,然后将用户名密码等参数封装成一个 UsernamePasswordAuthenticationToken 对象,最后调用 AuthenticationManager#authenticate 方法进行验证,验证成功后会返回一个认证后的 Authentication 对象,再手动把该 Authentication 对象存入 SecurityContextHolder 中。
  配置完成后,重启项目,进行登录测试即可。
  第二种方案和第一种方案异曲同工,第二种实际上就是把第一种的底层拉出来自己重新实现, 仅此而已 。  3. 小结
  好啦,今天就和大家介绍了两种 Spring Security DIY 登录的方案,这些方案可能工作中并不常用,但是对于大家理解 Spring Security 原理还是大有裨益的,感兴趣的小伙伴可以敲一下试试哦~

大数据开发基础之JAVAIO(一)本期给大家带来的是大数据开发基础中之JAVAIO的相关知识,IO全称InputStream,outputStream,是输入流输出流的意思,这是Java的核心库java。io提供了APHP医院用HoloLens2Dynamics365革新外科手术查看引用信息源请点击映维网利用混合现实来优化和最大限度地提高外科手术的安全性(映维网2021年10月21日)外科医生越来越多地利用尖端技术来确保手术尽可能安全,并帮助提高患者护理质网友称iQOOZ3是千元机天花板,它有这个实力吗?作为当代年轻人,喜新厌旧乃是常态心理,所以我对智能手机的选择问题上也相对谨慎。之所以这么说,主要是因为我的换机频率实在太高,即便是入手了果子机也就能用个一年半载,所以千元机更适合我苹果CEO库克我可能在10年内卸任!网友接班人是谁?作为全球科技数码领域巨头企业,苹果可谓是家喻户晓的品牌。当然,不少人平时所关注的也并不只是iPhone手机而已。近日,苹果CEO蒂姆库克(TimCook)在接受某媒体采访时表示,可苹果因包装盒中不标配充电头被罚200万美元!网友罚少了去年,苹果在发布iPhone12时以环保为由取消了手机包装中标配的充电器配件,此举在国内外引起了业内外人士的各种发声。据外媒(Tilt)消息称,由于iPhone12和新版本iPhoWindows11性能曝光!网友发现其多核比Win10差了10?之前微软已宣布,将于6月24日的发布会上宣布新一代Windows系统了,不过大家现在都知道这个是Windows11(以下简称Win11)了,UI界面改动不少。至于Win11的性能,北京考生为快递小哥送上祝福!网友150字也不够啊今年是与众不同的一年,突如其来的新冠肺炎改变了很多人的生活状态,对于学生的影响尤为明显。各学校纷纷发起了停课不停学的教学模式,但是对于高三考生来说显得更为紧张,返校上课高考延期,让乳品巨头阿尔乐用HoloLens2混合现实技术进行全球工厂的生产维护查看引用信息源请点击映维网保持关键业务连续性和快速性(映维网2021年10月28日)阿尔乐是世界最大的乳品公司之一。由于大部分经验机器操作员都受疫情出行限制影响,团队需要寻找保持关胆大你就来,义庄派对惊叫来袭,登陆NOLOSonic应用商店声明新闻稿非映维官方稿,法律问题一律与映维无关万圣节玩什么?必然要选择恐怖游戏把节日气氛拉倒最满啊!NOLO现在就给大家安排上,中国僵尸题材恐怖游戏义庄派对恐怖来袭!登陆NOLOSSLAM动态特征身形图深度学习,Facebook提出全身姿态捕捉新方案(映维网2021年10月27日)增强现实和虚拟现实中的真正沉浸式体验需要由用户姿态的显式表征所驱动。特别地,其需要从设备的角度估计用户的姿态,这隐含地对应于以自我为中心的角度,亦即VR益智游戏方块主义登陆PicoStore首周7折优惠开启益智挑战声明新闻稿非映维官方稿,法律问题一律与映维无关10月28日(本周四)上午1000,曾获BitAwards2019年度最佳XR游戏奖提名及比利时游戏奖2019年度最佳ARVRMR提名
广东提出互联网农村改革,提高农民收入,互联网大佬入局当前世界经济发展极不稳定,提高农村地区人民的收入,保持社会稳定成了一个很重要的事情。所以号召互联网企业深入农村地区,探索出一条适合农村地区的互联网改革方案,促进农民收入提高农村消费新IT绿色推动中国智慧城市迈入3。0时代5月24日,依托智慧服务共创新型智慧城市2022智慧城市白皮书于北京正式发布。白皮书由联想集团携国内四家权威机构国家工业信息安全发展研究中心中国产业互联网发展联盟工业大数据分析与集续写春天的故事贵州打造算力保障基地经济日报贵阳5月23日讯(记者吴秉泽王新伟)今年以来,贵州加快发展数据中心产业集群智能终端产业集群数据应用产业集群等三个千亿级产业集群,力争打造面向全国的算力保障基地。贵安新区是贵聊天记录删除了怎样防止恢复?手机是现在移动互联网终端最普及的工具,人们通过手机就可以了解外面的世界。每天频繁地使用手机,里面产生了无数的重要隐私信息。在互联网信息时代,我人们也离不开手机,但是使用手机又会担心在澳大利亚发现的金字塔形状的古墓你去过埃及金字塔吗?你知道埃及和南美洲不是唯一能看到金字塔的地方吗?如今,在波斯尼亚和克里米亚也发现了类似的设计。但谁会想到澳大利亚会有金字塔呢?它们确实存在这些土丘过去被认为是自12箱快递被扔垃圾场当事人已起诉顺丰,6月1日开庭三言财经5月24日消息,2021年6月发生的顺丰将客户寄送的12箱物品当垃圾扔掉一事有了新进展。今日,事件当事人王子舍发文称,2022年3月,自己在北京市顺义区人民法院起诉了北京顺快手董事长被带走调查?紧急回应假的,已报案点蓝字关注,不迷路有市场传言称,快手董事长宿华疑于四月底被有关部门带走配合调查。5月23日晚间,快手回复证券时报券商中国记者称,已正式向公安机关报案并启动法律程序,坚决维护公司和宿目前都有哪些国产操作系统?近年来,国产操作系统究竟哪家强的话题持续升温,忽如一夜春风来,国内刮起了推广国产操作系统风潮。国内有很多不错的操作系统研发公司,但操作系统的范畴很广,很难分高低,在不同的领域,都有Spring事务传播机制事务是逻辑处理原性的保证段,通过使事务控制,可以极地避免出现逻辑处理失败导致的脏数据等问题。TransactionalTransactional是声明式事务的注解,可以被标记在类上游戏周报B站4款游戏涉隐私不合规,剑网3缘起公测拒绝未成年玩家南方财经全媒体实习生余述怀记者吴立洋北京报道在5月第2周结束之际,这一周游戏领域又发生了哪些值得关注的事件?在行业动向方面,福布斯发布了2022年最具价值电竞公司榜,北美电竞俱乐部塞尔维亚的传奇KaranAcoustics佳龙的品牌故事塞尔维亚的传奇KaranAcoustics佳龙的品牌故事品牌故事KaranAcoustics(佳龙)是什么?可能好些发烧友对这个品牌KaranAcoustics不是很熟悉,它是一个