最近看了一些微服务中一些安全认证的代码,感到很懵,很多相关的基础都不是很了解。就想到了大概两年前在慕课网 买的一门课程Spring Security相关的课程,一直没来得及好好学习,借此机会重基础开始学习,并且记录一下学习的 笔记。课程链接如下: https://coding.imooc.com/learn/list/134.html
1-引入依赖: 使用Spring Security首先需要在项目中引入相关的依赖。我这里创建了一个spring boot的项目。就引入了: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> 当我们引入依赖后,什么都不配置的时候,启动项目会有如下情况: 默认spring security 会保护我们所有的请求,访问任何请求都需要先进行身份认证。进入到一个登陆的页面。 并且在控制台会有打印的密码。 这种情况肯定不符合我们的要求,那我们应该怎么办?
2-覆盖spring securiy的默认配置 对于上面的问题,我们可以覆盖spring securiy的默认配置。 首先我们实现一个Configuration注解的类并且继承WebSecurityConfigurerAdapter:专门做web应用的适配器. 覆盖其方法: configure(HttpSecurity http) http.formLogin() .and() .authorizeRequests() .anyRequest() .authenticated(); 上面的配置代表使用表单登录进行身份认证,所有的请求都需要进行身份认证。
3-自定义用户认证逻辑 我们知道了如何覆盖spring securiy的默认配置,接下来就来看看如何自定义用户认证逻辑。 首先我们需要实现UserDetailsService接口,在其loadUserByUsername方法中我们可以自定义用户信息。 比如以下流程: 1-根据用户名去数据库查询用户信息,如密码,是否过期等 2-组装为UserDetails对象然后返回。 spring securiy是一组过滤器,当我们在from表单填入用户名和密码的时候,会进入 UsernamePasswordAuthenticationFilter这个过滤器,它是专门用来处理表单登录请求的过滤器。 这这个过滤器内,它会接收表单传入的用户名和密码,然后进行认证的判断。 我们这里分析一下它是如何进行密码判断的? 首先页面输入了用户名和密码 然后进入了UsernamePasswordAuthenticationFilter过滤器去处理我们的登录请求。 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); 在authenticate方法内部它会从UsernamePasswordAuthenticationToken中获取到username, 然后会调用我们自己实现的UserDetailsService来获取用户信息。 UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username); 然后会根据获取的用户信息进行一系列的判断: preAuthenticationChecks.check(user); 比如是否过期,是否被冻结,这些信息我们都可以存入库中,查询处理返回给UserDetails 。 然后会对密码进行校验: if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) 这里会获取页面传入的密码和数据库中保存的密码进行校验。 并且使用了passwordEncoder。 passwordEncoder我们可以自定义,在保存用户密码的时候需要使用passwordEncoder对密码加密然后入库。 @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); }
4-个性化用户认证流程 有时候我们需要使用自己的登录页面可以做如下配置: .loginPage("/free-signIn.html") .antMatchers("/free-signIn.html").permitAll() //告诉spring security 在UsernamePasswordAuthenticationFilter去处理我们配置的请求然后去获取用户信息 .loginProcessingUrl("/authentication/form") .antMatchers(new String[]{"/free-signIn.html","/js/**","/css/**","/img/**", "/images/**","/fonts/**","/**/favicon.ico"}).permitAll() 可以更加灵活比如: 处理不同类型的请求: 访问需要保护的html 访问需要保护的接口。 配置跳转到自定义的controller方法上: .loginPage("/authentication/require") 完整代码如下: //当需要身份认证的时候,跳转到这里 @RequestMapping("/authentication/require") @ResponseStatus(code = HttpStatus.UNAUTHORIZED) public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException { SavedRequest savedRequest=requestCache.getRequest(request,response); if(savedRequest != null){ String targetUrl=savedRequest.getRedirectUrl(); log.info("引发跳转的请求是:"+targetUrl); if(StringUtils.endsWithIgnoreCase(targetUrl,".html")){ redirectStrategy.sendRedirect(request,response,securityProperties.getBrowser().getLoginPage()); } } return new SimpleResponse("访问服务需要身份认证,请引导用户到登录页面"); }
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦