CAS5.2 增加验证码 错误提示 配置Redis

颜嘉福
2023-12-01

CAS增加验证码是通过修改验证的Credential实现的

1 重写Credential

public class UsernamePasswordCaptchaCredential implements Credential, Serializable {

    /**
     * Authentication attribute name for password.
     **/
    public static final String AUTHENTICATION_ATTRIBUTE_PASSWORD = "credential";

    private static final long serialVersionUID = -700605081472810939L;

    private String username;

    private String password;

    private String captcha;

    public UsernamePasswordCaptchaCredential() {
    }

    public UsernamePasswordCaptchaCredential(String userName, String password, String captcha) {
        this.username = userName;
        this.password = password;
        this.captcha = captcha;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(final String userName) {
        this.username = userName;
    }

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

    @Override
    public String getId() {
        return this.username;
    }

    @Override
    public String toString() {
        return this.username;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof UsernamePasswordCaptchaCredential)) return false;
        UsernamePasswordCaptchaCredential that = (UsernamePasswordCaptchaCredential) o;
        return Objects.equals(getUsername(), that.getUsername()) &&
                Objects.equals(getPassword(), that.getPassword()) &&
                Objects.equals(getCaptcha(), that.getCaptcha());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getUsername(), getPassword(), getCaptcha());
    }
}

2 重新配置webflow流程

public class CaptchaWebflowConfigurer extends DefaultWebflowConfigurer {

    public CaptchaWebflowConfigurer(FlowBuilderServices flowBuilderServices, FlowDefinitionRegistry loginFlowDefinitionRegistry, ApplicationContext applicationContext, CasConfigurationProperties casProperties) {
        super(flowBuilderServices, loginFlowDefinitionRegistry, applicationContext, casProperties);
    }

    @Override
    protected void createRememberMeAuthnWebflowConfig(Flow flow) {
        if (this.casProperties.getTicket().getTgt().getRememberMe().isEnabled()) {
            this.createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, RememberMeUsernamePasswordCredential.class);
            ViewState state = (ViewState) this.getState(flow, CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM, ViewState.class);
            BinderConfiguration cfg = this.getViewStateBinderConfiguration(state);
            cfg.addBinding(new BinderConfiguration.Binding("rememberMe", (String) null, false));
        } else {
            this.createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, UsernamePasswordCaptchaCredential.class);
            ViewState state = (ViewState) this.getState(flow, CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM, ViewState.class);
            BinderConfiguration cfg = this.getViewStateBinderConfiguration(state);
            cfg.addBinding(new BinderConfiguration.Binding("captcha", (String) null, true));
        }
    }

}

3 之前的SpringConfig

@Configuration
@EnableConfigurationProperties(CasConfigurationProperties.class)
@AutoConfigureBefore(value = CasWebflowContextConfiguration.class)
@ComponentScan(basePackages = {"com.sugon.itos.web.sso.*"})
public class SpringConfig {
    @Autowired
    private CasConfigurationProperties casProperties;

    @Autowired
    private FlowDefinitionRegistry loginFlowRegistry;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private FlowBuilderServices flowBuilderServices;

    @Bean
    public CasWebflowConfigurer customWebflowConfigurer() {
        final CaptchaWebflowConfigurer c = new CaptchaWebflowConfigurer(flowBuilderServices, loginFlowRegistry, applicationContext, casProperties);
        c.initialize();
        return c;
    }
}

4 修改login-webflow.xml

<view-state id="viewLoginForm" view="casLoginView" model="credential">
        <binder>
            <binding property="username" required="true"/>
            <binding property="password" required="true"/>
            <binding property="captcha" required="false"/>
        </binder>
        <transition on="submit" bind="true" validate="true" to="realSubmit" history="invalidate"/>
    </view-state>

5 修改casLoginView.html 加上验证码

<section class="row" id="captchaShow" style="display: none;">
    <div>
        <input type="text" class="required"
        id="captcha"
        placeholder="验证码"
        th:field="*{captcha}" autocomplete="off"/>
        <span style="vertical-align: bottom;">
            <img  id="createCode"  class="createCode" src=""  />
            <span id="refreshCode" class="icon-refresh glyphicon glyphicon-refresh"></span>
        </span>
    </div>
</section>

这样就能提交并接受到验证码参数了

验证码一般都存在Redis中,按IP进行限制。下面配置Redis

1 新增RedisConfig
注意:CAS在Redis票据处理时已经有了RedisConnectFactory了,所以就用它的了,不用自己在配置新的参数了。


@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间
        //cacheManager.setDefaultExpiration(60);//秒
        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.afterPropertiesSet();
        RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer(); 
        redisTemplate.setKeySerializer(stringRedisSerializer);
        return redisTemplate;
    }

}

现在就可以在别的地方使用Redis了

@Autowired
private RedisService redisService;

CAS 返回验证码无效的提示

1 写一个异常, 在需要提示的业务处抛出即可

/**
 * 验证码错误异常
 */
public class CaptchaException extends AccountExpiredException {

    private static final long serialVersionUID = -3647157853533346879L;

    public CaptchaException() {
        super();
    }

    public CaptchaException(String msg) {
        super(msg);
    }

}

2 在application 文件中配置

cas.authn.exceptions.exceptions= com.sugon.itos.web.sso.exception.CaptchaException

3 在message_zh_CN.properties里添加对应提示词

authenticationFailure.CaptchaException=验证码错误

成功

 类似资料: