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>
这样就能提交并接受到验证码参数了
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;
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=验证码错误
成功