1.短信登录配置及重构

  • 短信登录一部分配置主要是配置以下3个组件:

image.png
主要是配置:SmsCodeAuthenticationFilter和SmsCodeAuthenticationProvider;

SmsCodeAuthenticationToken是封装数据,是不用配置的。

  • 另一部分配置是短信过滤器配置:SmsCodeFilter

1.1 过滤器链上组件配置

我们在spring-security-core项目创建一个SmsCodeAuthenticationSecurityConfig;我们没有向之前WebSecurityConfig一样配置在spring-security-web里面;原因是因为:短信校验模块这段配置后面我们既要在web浏览器端使用还要在App端使用。所以我们单独提出一个类。

@Configuration
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

    @Autowired
    private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler myAuthenticationFailureHandler;

    @Autowired
    private UserDetailsService myUserDetailsService;

    @Override
    public void configure(HttpSecurity http) throws Exception {
      /*  super.configure(builder);*/
        //1.按照过滤器链路:配置SmsCodeAutnenticationFilter-->配置让其加入到AuthenticationManager中  配置其成功处理  失败处理的Handler
        SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
        smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler);
        smsCodeAuthenticationFilter.setAuthenticationFailureHandler(myAuthenticationFailureHandler);

        //2.配置SmsCodeAuthenticationProvider-->添加UserDetailService
        SmsCodeAuthenticationProvider smsCodeAuthenticationProvider = new SmsCodeAuthenticationProvider();
        smsCodeAuthenticationProvider.setUserDetailsService(myUserDetailsService);

        //3.http配置:配置SmsCodeAutnenticationFilter执行位置--->在UsernamePasswordAuthenticationFilter之后
        http.authenticationProvider(smsCodeAuthenticationProvider)
                .addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

    }
}

1.2 验证码过滤器配置

在Spring-security-web里面配置:SmsCodeFilter在UsernamePasswordFilter前面
image.png

1.3 SmsCodeAuthenticationSecurityConfig配置到WebSecurityConfig

我们把spring-security-core里面的SmsCodeAuthenticationSecurityConfig也配置导入到spring-security-web下面的:WebSecurityConfig配置中:
image.png

1.4 测试查看效果

http://127.0.0.1:8088/login.html

image.png

  1. 点击短信登录的登录后返回:

image.png

  1. 点击发送验证码
向手机:13012345678 发送短信验证码:711828  
  1. 我们输入短信验证码,然后登录

image.png
得出结果:
image.png

2.短信登录重构

现在为止,两种登录方式都已经开发完了。

  1. 他们都可以在一个系统里面同时生效。
  2. 底层都是Spring Security,采用的是同一种机制和流程,但是认证的逻辑是不同的。

目前代码重构主要是做两方面内容:
消除重复: 短信验证码和图形验证码里面重复的代码,因为我们是做的拷贝粘铁,然后做了一些简单修改。实现的短信验证码校验功能。 重复的代码是代码坏味道 里面最常见和最严重的。他使得你的代码难以维护,虽然开发时候挺快的,一旦业务逻辑变化,修改代码时候,你可能需要把复制粘贴地方都要修改。重复一个功能模块、小到配置项:比如:在WebSecurityConfig里面:
image.png

WebSecurityController里面:
image.png

都有相同的代码:/authentication/require
以上修改的时候,你同样需要改变一下,改了一个地方,另一个地方忘记改了,也会出问题。

  1. 配置抽象:就像我们把短信验证码授权安全配置一样:SmsCodeAuthenticationSecurityConfig 单独抽象到一个类里面。所以这里我们把验证码统一都抽象出来,短信验证码、图形验证码。短信配置的话 也放到一个配置里面去。

image.png

  1. 不管在app端,还是浏览器端应用的一些配置我们都抽取到spring-security-core里面
  2. 上面基本配置都封装成各个类的话,这样的话在WebSecurityConfig里面只剩下其特有的配置代码;比如:remeberMe就是其特有代码。remeberMe实现是基于往浏览器里面写cookie实现。
  3. App里面我们会单独写一个AppSecurityConfig配置代码
  4. 这样的话AppSecurityConfig、WebSecurityConfig可以使用如下引用方法去引用:

image.png

AppSecurityConfig、WebSecurityConfig需要支持认证登录的话都得配置。

2.1 验证码校验过滤器合并成一个

验证码校验过滤器合并成一个ValidateCodeFilter;其启动时候会根据系统的配置:
image.png

读取到一个map里面去:

/**
 * 存放所有需要校验验证码的url
 */
private Map<String, ValidateCodeType> urlMap = new HashMap<>();

里面存放着什么样的验证码使用什么样的处理器。
根据依赖查找查找到对应的校验码处理器:

image.png

2.2 密码相关配置抽象

定义一个抽象类:AbstractChannelSecurityConfig 把密码相关配置放在里面。

/*
* @author yexinming
* @date 2020/2/27
*/
public class AbstractChannelSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
protected AuthenticationSuccessHandler myAuthenticationSuccessHandler;

@Autowired
protected AuthenticationFailureHandler myAuthenticationFailureHandler;

protected void applyPasswordAuthenticationConfig(HttpSecurity http) throws Exception {

http.formLogin()
.loginPage(SecurityConstants.DEFAULT_UNAUTHENTICATION_URL)
.loginProcessingUrl(SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_FORM)
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(myAuthenticationFailureHandler);
}
}

2.3 所有模块配置抽象出来

image.png

2.4 字符串抽象

将常用配置项配置到SecurityContants中:

public interface SecurityConstants {
    /**
     * 默认的处理验证码的url前缀
     */
    public static final String DEFAULT_VALIDATE_CODE_URL_PREFIX = "/code";
    /**
     * 当请求需要身份认证时,默认跳转的url
     *
     * @see SecurityController
     */
    public static final String DEFAULT_UNAUTHENTICATION_URL = "/authentication/require";
    /**
     * 默认的用户名密码登录请求处理url
     */
    public static final String DEFAULT_LOGIN_PROCESSING_URL_FORM = "/authentication/form";
    /**
     * 默认的手机验证码登录请求处理url
     */
    public static final String DEFAULT_LOGIN_PROCESSING_URL_MOBILE = "/authentication/mobile";
    /**
     * 默认登录页面
     *
     * @see SecurityController
     */
    public static final String DEFAULT_LOGIN_PAGE_URL = "/login.html";
    /**
     * 验证图片验证码时,http请求中默认的携带图片验证码信息的参数的名称
     */
    public static final String DEFAULT_PARAMETER_NAME_CODE_IMAGE = "imageCode";
    /**
     * 验证短信验证码时,http请求中默认的携带短信验证码信息的参数的名称
     */
    public static final String DEFAULT_PARAMETER_NAME_CODE_SMS = "smsCode";
    /**
     * 发送短信验证码 或 验证短信验证码时,传递手机号的参数的名称
     */
    public static final String DEFAULT_PARAMETER_NAME_MOBILE = "mobile";
    /**
     * session失效默认的跳转地址
     */
    public static final String DEFAULT_SESSION_INVALID_URL = "/session/invalid";
}

image.png


startshineye
91 声望26 粉丝

我在规定的时间内,做到了我计划的事情;我自己也变得自信了,对于外界的人跟困难也更加从容了,我已经很强大了。可是如果我在规定时间内,我只有3分钟热度,哎,我不行,我就放弃了,那么这个就是我自己的问题,因为你自己...


引用和评论

0 条评论