提交 0c467a72 编写于 作者: M MaxKey

captcha config

上级 eb0d1e12
......@@ -28,9 +28,9 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
......@@ -48,10 +48,6 @@ public class ImageCaptchaEndpoint {
@Autowired
private Producer captchaProducer;
@Value("${maxkey.login.captcha.type}")
private String captchaType;
/**
* captcha image Producer.
......@@ -60,9 +56,11 @@ public class ImageCaptchaEndpoint {
* @param response HttpServletResponse
*/
@RequestMapping(value = "/captcha")
public void captchaHandleRequest(HttpServletRequest request, HttpServletResponse response) {
public void captchaHandleRequest(HttpServletRequest request,
HttpServletResponse response,
@RequestParam(value="captcha",required=false,defaultValue="text") String captchaType) {
try {
String kaptchaText = captchaProducer.createText();
if (captchaType.equalsIgnoreCase("Arithmetic")) {
Integer intParamA = Integer.valueOf(kaptchaText.substring(0, 1));
......@@ -127,11 +125,6 @@ public class ImageCaptchaEndpoint {
}
}
}
public void setCaptchaType(String captchaType) {
this.captchaType = captchaType;
}
public void setCaptchaProducer(Producer captchaProducer) {
this.captchaProducer = captchaProducer;
......
......@@ -203,8 +203,7 @@ public abstract class AbstractAuthenticationProvider {
*/
protected void captchaValid(String captcha, String authType) {
// for basic
if (applicationConfig.getLoginConfig().isCaptcha()
&& authType.equalsIgnoreCase(AuthType.NORMAL)) {
if (authType.equalsIgnoreCase(AuthType.NORMAL)) {
_logger.info("captcha : "
+ WebContext.getSession().getAttribute(
WebConstants.KAPTCHA_SESSION_KEY).toString());
......
......@@ -24,6 +24,7 @@ import org.maxkey.authn.online.OnlineTicketServices;
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.Institutions;
import org.maxkey.entity.UserInfo;
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
import org.maxkey.password.onetimepwd.OtpAuthnService;
......@@ -84,8 +85,11 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
//jwtTokenValid(j_jwtToken);
authTypeValid(loginCredential.getAuthType());
captchaValid(loginCredential.getCaptcha(),loginCredential.getAuthType());
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
if(inst.getCaptcha().equalsIgnoreCase("YES")) {
captchaValid(loginCredential.getCaptcha(),loginCredential.getAuthType());
}
emptyPasswordValid(loginCredential.getPassword());
......
......@@ -22,19 +22,10 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class LoginConfig {
@Value("${maxkey.login.captcha}")
boolean captcha;
//验证码类型 text 文本 , arithmetic算术验证码
@Value("${maxkey.login.captcha.type:text}")
String captchaType;
@Value("${maxkey.login.mfa}")
boolean mfa;
@Value("${maxkey.login.socialsignon}")
boolean socialSignOn;
@Value("${maxkey.login.kerberos}")
boolean kerberos;
......@@ -43,9 +34,6 @@ public class LoginConfig {
@Value("${maxkey.login.wsfederation}")
boolean wsFederation;
@Value("${maxkey.login.default.uri}")
String defaultUri;
/**
* .
......@@ -53,21 +41,7 @@ public class LoginConfig {
public LoginConfig() {
}
public boolean isCaptcha() {
return captcha;
}
public void setCaptcha(boolean captcha) {
this.captcha = captcha;
}
public boolean isSocialSignOn() {
return socialSignOn;
}
public void setSocialSignOn(boolean socialSignOn) {
this.socialSignOn = socialSignOn;
}
public boolean isKerberos() {
return kerberos;
......@@ -85,13 +59,7 @@ public class LoginConfig {
this.mfa = mfa;
}
public String getDefaultUri() {
return defaultUri;
}
public void setDefaultUri(String defaultUri) {
this.defaultUri = defaultUri;
}
public boolean isRemeberMe() {
return remeberMe;
......@@ -109,35 +77,19 @@ public class LoginConfig {
this.wsFederation = wsFederation;
}
public String getCaptchaType() {
return captchaType;
}
public void setCaptchaType(String captchaType) {
this.captchaType = captchaType;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("LoginConfig [captcha=");
builder.append(captcha);
builder.append(", captchaType=");
builder.append(captchaType);
builder.append(", mfa=");
builder.append(mfa);
builder.append(", socialSignOn=");
builder.append(socialSignOn);
builder.append(", kerberos=");
builder.append(kerberos);
builder.append(", remeberMe=");
builder.append(remeberMe);
builder.append(", wsFederation=");
builder.append(wsFederation);
builder.append(", defaultUri=");
builder.append(defaultUri);
builder.append("]");
return builder.toString();
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("LoginConfig [mfa=");
builder.append(mfa);
builder.append(", kerberos=");
builder.append(kerberos);
builder.append(", remeberMe=");
builder.append(remeberMe);
builder.append(", wsFederation=");
builder.append(wsFederation);
builder.append("]");
return builder.toString();
}
}
......@@ -44,14 +44,6 @@ public class Institutions extends JpaBaseEntity implements Serializable {
@Column
private String fullName;
@Column
private String logo;
@Column
private String title;
@Column
private String consoleTitle;
@Column
private String domain;
@Column
private String division;
@Column
private String country;
......@@ -76,8 +68,25 @@ public class Institutions extends JpaBaseEntity implements Serializable {
@Column
private String description;
@Column
private int status;
@Column
private String logo;
@Column
private String title;
@Column
private String consoleTitle;
@Column
private String domain;
@Column
private String captcha;
@Column
private String captchaSupport;
@Column
private String defaultUri;
@Column
String createdBy;
@Column
......@@ -236,6 +245,33 @@ public class Institutions extends JpaBaseEntity implements Serializable {
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
public String getCaptchaSupport() {
return captchaSupport;
}
public boolean isCaptchaSupport() {
return (captchaSupport !=null && captchaSupport.equalsIgnoreCase("YES") ? true : false);
}
public void setCaptchaSupport(String captchaSupport) {
this.captchaSupport = captchaSupport;
}
public String getDefaultUri() {
return defaultUri;
}
public void setDefaultUri(String defaultUri) {
this.defaultUri = defaultUri;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
......
......@@ -104,6 +104,9 @@ public class InstitutionsRepository {
institution.setDomain(rs.getString("domain"));
institution.setTitle(rs.getString("title"));
institution.setConsoleTitle(rs.getString("consoletitle"));
institution.setCaptcha(rs.getString("captcha"));
institution.setCaptchaSupport(rs.getString("CaptchaSupport"));
institution.setDefaultUri(rs.getString("DefaultUri"));
return institution;
}
}
......
......@@ -56,36 +56,36 @@ public class SocialSignOnListController {
public ModelAndView forwardUpdate() {
ModelAndView modelAndView=new ModelAndView("social/socialSignOnProvider");
if(applicationConfig.getLoginConfig().isSocialSignOn()){
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
List<SocialsProvider> listSocialSignOnProvider =
socialSignOnProviderService.loadSocialsProviders(inst.getId()).getSocialSignOnProviders();
SocialsAssociate socialSignOnUser=new SocialsAssociate();
socialSignOnUser.setUserId(WebContext.getUserInfo().getId());
List<SocialsAssociate> listSocialSignOnUserToken= socialSignOnUserService.query(socialSignOnUser);
List<SocialsProvider> listBindSocialSignOnProvider=new ArrayList<SocialsProvider>();
_logger.debug("list SocialSignOnProvider : "+listSocialSignOnProvider);
_logger.debug("list SocialSignOnUserToken : "+listSocialSignOnUserToken);
for (SocialsProvider ssop : listSocialSignOnProvider){
SocialsProvider socialSignOnProvider=new SocialsProvider();
socialSignOnProvider.setProvider(ssop.getProvider());
socialSignOnProvider.setProviderName(ssop.getProviderName());
socialSignOnProvider.setIcon(ssop.getIcon());
socialSignOnProvider.setSortOrder(ssop.getSortOrder());
for(SocialsAssociate ssout :listSocialSignOnUserToken){
if(ssout.getProvider().equals(ssop.getProvider())){
socialSignOnProvider.setUserBind(true);
socialSignOnProvider.setBindTime(ssout.getCreatedDate());
socialSignOnProvider.setLastLoginTime(ssout.getUpdatedDate());
_logger.debug("binded provider : "+ssout.getProvider());
}
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
List<SocialsProvider> listSocialSignOnProvider =
socialSignOnProviderService.loadSocialsProviders(inst.getId()).getSocialSignOnProviders();
SocialsAssociate socialSignOnUser=new SocialsAssociate();
socialSignOnUser.setUserId(WebContext.getUserInfo().getId());
List<SocialsAssociate> listSocialSignOnUserToken= socialSignOnUserService.query(socialSignOnUser);
List<SocialsProvider> listBindSocialSignOnProvider=new ArrayList<SocialsProvider>();
_logger.debug("list SocialSignOnProvider : "+listSocialSignOnProvider);
_logger.debug("list SocialSignOnUserToken : "+listSocialSignOnUserToken);
for (SocialsProvider ssop : listSocialSignOnProvider){
SocialsProvider socialSignOnProvider=new SocialsProvider();
socialSignOnProvider.setProvider(ssop.getProvider());
socialSignOnProvider.setProviderName(ssop.getProviderName());
socialSignOnProvider.setIcon(ssop.getIcon());
socialSignOnProvider.setSortOrder(ssop.getSortOrder());
for(SocialsAssociate ssout :listSocialSignOnUserToken){
if(ssout.getProvider().equals(ssop.getProvider())){
socialSignOnProvider.setUserBind(true);
socialSignOnProvider.setBindTime(ssout.getCreatedDate());
socialSignOnProvider.setLastLoginTime(ssout.getUpdatedDate());
_logger.debug("binded provider : "+ssout.getProvider());
}
listBindSocialSignOnProvider.add(socialSignOnProvider);
}
modelAndView.addObject("listSocialSignOnProvider", listBindSocialSignOnProvider);
listBindSocialSignOnProvider.add(socialSignOnProvider);
}
modelAndView.addObject("listSocialSignOnProvider", listBindSocialSignOnProvider);
return modelAndView;
}
......
......@@ -24,6 +24,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.Institutions;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -53,10 +55,11 @@ public class IndexEndpoint {
public ModelAndView forwardindex(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
_logger.debug("IndexEndpoint /forwardindex.");
String defaultUri = applicationConfig.getLoginConfig().getDefaultUri();
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
String defaultUri = inst.getDefaultUri();
if (defaultUri != null && !defaultUri.equals("")) {
_logger.debug("defaultUri " + defaultUri);
return WebContext.redirect(applicationConfig.getLoginConfig().getDefaultUri());
return WebContext.redirect(defaultUri);
}
_logger.debug("Uri /appList");
return new ModelAndView("/appList");
......
......@@ -122,15 +122,13 @@ public class LoginEndpoint {
if( applicationConfig.getLoginConfig().isKerberos()){
modelAndView.addObject("userDomainUrlJson", kerberosService.buildKerberosProxys());
}
modelAndView.addObject("isCaptcha", applicationConfig.getLoginConfig().isCaptcha());
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
modelAndView.addObject("isCaptcha", inst.isCaptchaSupport());
modelAndView.addObject("captcha", inst.getCaptcha());
modelAndView.addObject("sessionid", WebContext.getSession().getId());
//modelAndView.addObject("jwtToken",jwtLoginService.buildLoginJwt());
//load Social Sign On Providers
if(applicationConfig.getLoginConfig().isSocialSignOn()){
_logger.trace("Load Social Sign On Providers ");
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
modelAndView.addObject("sspLogin", socialSignOnProviderService.loadSocialsProviders(inst.getId()));
}
modelAndView.addObject("sspLogin", socialSignOnProviderService.loadSocialsProviders(inst.getId()));
Object loginErrorMessage=WebContext.getAttribute(WebConstants.LOGIN_ERROR_SESSION_MESSAGE);
modelAndView.addObject("loginErrorMessage", loginErrorMessage==null?"":loginErrorMessage);
......
......@@ -48,10 +48,6 @@ maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH
############################################################################
#Login configuration #
############################################################################
#enable captcha
maxkey.login.captcha =${LOGIN_CAPTCHA:true}
#text or arithmetic
maxkey.login.captcha.type =${LOGIN_CAPTCHA_TYPE:text}
#enable two factor,use one time password
maxkey.login.mfa =${LOGIN_MFA_ENABLED:true}
#TimeBasedOtpAuthn MailOtpAuthn SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
......@@ -69,8 +65,7 @@ maxkey.login.remeberme.validity =0
#JWT support
maxkey.login.jwt =${LOGIN_JWT:true}
maxkey.login.jwt.issuer =${LOGIN_JWT_ISSUER:${maxkey.server.authz.uri}}
#to default application web site
maxkey.login.default.uri =appList
#whitelist
maxkey.ipaddress.whitelist =false
#notices show
maxkey.notices.visible =false
......
......@@ -49,10 +49,6 @@ maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH
############################################################################
#Login configuration #
############################################################################
#enable captcha
maxkey.login.captcha =${LOGIN_CAPTCHA:true}
#text or arithmetic
maxkey.login.captcha.type =${LOGIN_CAPTCHA_TYPE:text}
#enable two factor,use one time password
maxkey.login.mfa =${LOGIN_MFA_ENABLED:true}
#TimeBasedOtpAuthn MailOtpAuthn SmsOtpAuthnYunxin SmsOtpAuthnAliyun SmsOtpAuthnTencentCloud
......@@ -70,8 +66,7 @@ maxkey.login.remeberme.validity =0
#JWT support
maxkey.login.jwt =${LOGIN_JWT:true}
maxkey.login.jwt.issuer =${LOGIN_JWT_ISSUER:${maxkey.server.authz.uri}}
#to default application web site
maxkey.login.default.uri =appList
#whitelist
maxkey.ipaddress.whitelist =false
#notices show
maxkey.notices.visible =false
......
......@@ -38,7 +38,7 @@
<div class="input-group" >
<i class="fa fa-lock fa-2" ></i>
<input required="" class="form-control " type='text' id="j_captcha" name="captcha" tabindex="3" value="" style="float: left;" placeholder='<@locale code="login.text.captcha"/>'/>
<img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha"/>
<img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha?captcha=${captcha}"/>
</div >
</div >
</td>
......
......@@ -20,6 +20,7 @@ package org.maxkey.web.endpoint;
import org.maxkey.authn.AbstractAuthenticationProvider;
import org.maxkey.authn.LoginCredential;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.Institutions;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
......@@ -64,8 +65,10 @@ public class LoginEndpoint {
}
ModelAndView modelAndView = new ModelAndView();
Institutions inst = (Institutions)WebContext.getAttribute(WebConstants.CURRENT_INST);
modelAndView.addObject("isRemeberMe", applicationConfig.getLoginConfig().isRemeberMe());
modelAndView.addObject("isCaptcha", applicationConfig.getLoginConfig().isCaptcha());
modelAndView.addObject("isCaptcha", inst.isCaptchaSupport());
modelAndView.addObject("captcha", inst.getCaptcha());
modelAndView.addObject("sessionid", WebContext.getSession().getId());
Object loginErrorMessage=WebContext.getAttribute(WebConstants.LOGIN_ERROR_SESSION_MESSAGE);
modelAndView.addObject("loginErrorMessage", loginErrorMessage==null?"":loginErrorMessage);
......
......@@ -43,14 +43,8 @@ maxkey.server.message.queue =${SERVER_MESSAGE_QUEUE:none}
############################################################################
#Login configuration #
############################################################################
#enable captcha
maxkey.login.captcha =${LOGIN_CAPTCHA:true}
#text or arithmetic
maxkey.login.captcha.type =${LOGIN_CAPTCHA_TYPE:text}
#enable two factor,use one time password
maxkey.login.mfa =false
#enable social sign on
maxkey.login.socialsignon =false
#Enable kerberos/SPNEGO
maxkey.login.kerberos =false
#wsFederation
......@@ -59,9 +53,6 @@ maxkey.login.wsfederation =false
maxkey.login.remeberme =false
#validity
maxkey.login.remeberme.validity =0
#default.uri
#to appList page
maxkey.login.default.uri =appList
#ipaddress whitelist
maxkey.ipaddress.whitelist =false
#JWT support
......
......@@ -504,10 +504,6 @@ synchronizers.syncStartTime=\u533A\u95F4
institutions.name=\u7B80\u79F0
institutions.fullName=\u5168\u79F0
institutions.logo=\u56FE\u6807
institutions.title=\u7CFB\u7EDF\u540D\u79F0
institutions.consoleTitle=\u63A7\u5236\u53F0\u540D\u79F0
institutions.domain=\u57DF\u540D
institutions.division=\u5206\u652F\u673A\u6784
institutions.contact=\u8054\u7CFB\u4EBA
institutions.phone=\u7535\u8BDD
......@@ -520,6 +516,17 @@ institutions.street=\u8857\u9053
institutions.address=\u5730\u5740
institutions.postalcode=\u90AE\u7F16
institutions.logo=\u56FE\u6807
institutions.title=\u7CFB\u7EDF\u540D\u79F0
institutions.consoleTitle=\u63A7\u5236\u53F0\u540D\u79F0
institutions.domain=\u57DF\u540D
institutions.captchaSupport=\u9A8C\u8BC1\u7801\u652F\u6301
institutions.captcha=\u9A8C\u8BC1\u7801
institutions.captcha.type=\u9A8C\u8BC1\u7801\u7C7B\u578B
institutions.captcha.type.text=\u6570\u5B57
institutions.captcha.type.arithmetic=\u7B97\u672F
institutions.default.uri=\u9ED8\u8BA4\u5730\u5740
localization.property=\u5C5E\u6027
localization.langZh=\u4E2D\u6587
localization.langEn=\u82F1\u6587
......@@ -680,6 +687,7 @@ navs.resources=\u8D44\u6E90\u7BA1\u7406
navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
navs.notices=\u901A\u77E5\u516C\u544A
navs.institutions=\u673A\u6784\u914D\u7F6E
navs.institutions.system=\u7CFB\u7EDF\u4FE1\u606F
navs.socials.provider=\u793E\u4EA4\u670D\u52A1
navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
navs.ldapcontext=LDAP\u914D\u7F6E
......
......@@ -512,10 +512,6 @@ synchronizers.syncStartTime=During
institutions.name=name
institutions.fullName=fullName
institutions.logo=logo
institutions.title=Title
institutions.consoleTitle=ConsoleTitle
institutions.domain=domainName
institutions.division=division
institutions.contact=contact
institutions.phone=phone
......@@ -528,6 +524,17 @@ institutions.street=street
institutions.address=address
institutions.postalcode=postalcode
institutions.logo=logo
institutions.title=Title
institutions.consoleTitle=ConsoleTitle
institutions.domain=domainName
institutions.captchaSupport=captchaSupport
institutions.captcha=captcha
institutions.captcha.type=captchaType
institutions.captcha.type.text=Numeral
institutions.captcha.type.arithmetic=Arithmetic
institutions.default.uri=defaultUri
localization.property=Property
localization.langZh=Chinese
localization.langEn=English
......@@ -688,6 +695,7 @@ navs.resources=Resources
navs.adapters=Adapters
navs.notices=Notices
navs.institutions=Institutions
navs.institutions.system=System
navs.socials.provider=SocialsProvider
navs.synchronizers=Synchronizers
navs.ldapcontext=LdapContext
......
......@@ -503,10 +503,7 @@ synchronizers.syncStartTime=\u533A\u95F4
institutions.name=\u7B80\u79F0
institutions.fullName=\u5168\u79F0
institutions.logo=\u56FE\u6807
institutions.title=\u7CFB\u7EDF\u540D\u79F0
institutions.consoleTitle=\u63A7\u5236\u53F0\u540D\u79F0
institutions.domain=\u57DF\u540D
institutions.division=\u5206\u652F\u673A\u6784
institutions.contact=\u8054\u7CFB\u4EBA
institutions.phone=\u7535\u8BDD
......@@ -519,6 +516,17 @@ institutions.street=\u8857\u9053
institutions.address=\u5730\u5740
institutions.postalcode=\u90AE\u7F16
institutions.logo=\u56FE\u6807
institutions.title=\u7CFB\u7EDF\u540D\u79F0
institutions.consoleTitle=\u63A7\u5236\u53F0\u540D\u79F0
institutions.domain=\u57DF\u540D
institutions.captchaSupport=\u9A8C\u8BC1\u7801\u652F\u6301
institutions.captcha=\u9A8C\u8BC1\u7801
institutions.captcha.type=\u9A8C\u8BC1\u7801\u7C7B\u578B
institutions.captcha.type.text=\u6570\u5B57
institutions.captcha.type.arithmetic=\u7B97\u672F
institutions.default.uri=\u9ED8\u8BA4\u5730\u5740
localization.property=\u5C5E\u6027
localization.langZh=\u4E2D\u6587
localization.langEn=\u82F1\u6587
......@@ -679,6 +687,7 @@ navs.resources=\u8D44\u6E90\u7BA1\u7406
navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
navs.notices=\u901A\u77E5\u516C\u544A
navs.institutions=\u673A\u6784\u914D\u7F6E
navs.institutions.system=\u7CFB\u7EDF\u4FE1\u606F
navs.socials.provider=\u793E\u4EA4\u670D\u52A1
navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
navs.ldapcontext=LDAP\u914D\u7F6E
......
......@@ -38,7 +38,7 @@
<div class="input-group">
<span class="input-group-text fa fa-shield d-flex justify-content-center"></span>
<input id="j_captcha" name="captcha" class="form-control" value="" type="text" required="" placeholder="<@locale code="login.text.captcha"/>">
<img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha" />
<img id="j_captchaimg" class="captcha-image" src="<@base/>/captcha?captcha=${captcha}" />
</div>
</div>
......
......@@ -29,9 +29,10 @@ $(function(){
});
});
var captchaImageUrl = $('.captcha-image').attr("src");
//on captcha image click ,new a captcha code
$('.captcha-image').click(function () {//
$(this).attr("src", webContextPath + "/captcha?"+(new Date()).getTime());
$(this).attr("src", captchaImageUrl+"&"+(new Date()).getTime());
});
//passwdeye
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册