为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Security 入门

标签:
Java
最近看了一些微服务中一些安全认证的代码,感到很懵,很多相关的基础都不是很了解。就想到了大概两年前在慕课网
买的一门课程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 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
6396
获赞与收藏
157

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消