单点登录cas动态切换数据源

有些时候需要根据不同的客户端选择不同的数据源和不同的sql进行查询用户

那么

1,客户端必须传递参数,否则服务端不清楚是哪个客户端

2,服务端根据客户端传递参数,动态设置数据源和sql

3,使用sql和template验证用户

下面是请求和处理过程

1,请求http://127.0.0.1:8181/cas-server/login?service=http://127.0.0.1:8080/cas-client/cas&client=client1,这里多了个参数client=client1

2,到AuthenticationViaFormAction中根据参数设置数据源,下面是处理的类


package com.distinct.cas.jdbc;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;


import org.apache.commons.lang.StringUtils;
import org.jasig.cas.authentication.Credential;
import org.jasig.cas.authentication.RootCasException;
import org.jasig.cas.web.flow.AuthenticationViaFormAction;
import org.jasig.cas.web.support.WebUtils;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.webflow.execution.RequestContext;


/**
 * 验证码校验类
 * 
 * @author xiongyk
 * 
 */
public class AuthenticationViaFormActionWithAuthCode extends AuthenticationViaFormAction {

/**
* authcode check
*/
public final String validatorCode(final RequestContext context, final Credential credentials, final MessageContext messageContext) throws Exception {
final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
//接收客户端传参
String client = request.getParameter("client");
//可以根据参数确定用户访问的系统,从而根据确定要使用的sql语句和datasource,也就达到了动态切换数据源的目的
if("client1".equals(client)){
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
String sql = SpringPropertyPlaceholder.getProperty("client1.sql");
String dataSourceName = SpringPropertyPlaceholder.getProperty("client1.dataSource");
DataSource dataSource1 = (DataSource) ctx.getBean(dataSourceName);
QueryDatabaseAuthenticationHandler handler = (QueryDatabaseAuthenticationHandler) ctx.getBean("primaryAuthenticationHandler");
handler.setDataSource(dataSource1);//设置数据源会自动设置template
handler.setSql(sql);//设置sql
}else if("client2".equals(client)){
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
String sql = SpringPropertyPlaceholder.getProperty("client2.sql");
String dataSourceName = SpringPropertyPlaceholder.getProperty("client2.dataSource");
DataSource dataSource1 = (DataSource) ctx.getBean(dataSourceName);
QueryDatabaseAuthenticationHandler handler = (QueryDatabaseAuthenticationHandler) ctx.getBean("primaryAuthenticationHandler");
handler.setDataSource(dataSource1);//设置数据源会自动设置template
handler.setSql(sql);//设置sql
}else{//使用默认配置的数据源和sql语句
/*    p:dataSource-ref="${client.dataSource}" 
   p:passwordEncoder-ref="passwordEncoder" 
   p:sql="${client.sql}" 
   p:passwordEncoder="MD5PasswordEncoder" />*/
}



HttpSession session = request.getSession();
session.setAttribute("username", credentials.getId());
String authcode = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
session.removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);


UsernamePasswordCredentialWithAuthCode upc = (UsernamePasswordCredentialWithAuthCode) credentials;
String submitAuthcode = upc.getAuthcode();
if (StringUtils.isEmpty(submitAuthcode) || StringUtils.isEmpty(authcode) || !authcode.equals(submitAuthcode)) {
populateErrorsInstance(new BadAuthcodeAuthenticationException(), messageContext);
return "error";
} else {
return "success";
}
}


private void populateErrorsInstance(final RootCasException e, final MessageContext messageContext) {
try {
messageContext.addMessage(new MessageBuilder().error().code(e.getCode()).defaultText(e.getCode()).build());
} catch (final Exception fe) {
logger.error(fe.getMessage(), fe);
}
}
}

3,验证码验证的时候根据参数设置了数据源和sql,如果验证码验证通过,则根据数据源和sql验证用户名,密码等信息,下面是验证类,这样就实现了动态切换数据源的目的了

package com.distinct.cas.jdbc;


import java.security.GeneralSecurityException;
import java.util.Map;


import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.validation.constraints.NotNull;


import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.UsernamePasswordCredential;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;


/**
 * 通过数据库验证身份
 * 
 * @author huang
 *
 */
public class QueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {


@NotNull
private String sql;


protected final HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential) throws GeneralSecurityException, PreventedException {
// 获取用户名
String username = credential.getUsername();
try {
final Map values = getJdbcTemplate().queryForMap(this.sql, username);
String dbPassword = (String) values.get("password");
String salt = (String) values.get("salt");
String state = (String) values.get("state");
System.err.println("======= input username:(" + username + ")");
// 获取加密密码
String encryptedPassword = Md5.getMD5(credential.getPassword().trim(), salt);
System.err.println("======= input password:(" + encryptedPassword + ")");
System.out.println("======= sql:(" + this.sql + ")");
System.err.println("++++++ dbPassword:(" + dbPassword.trim() + ")");


if (!(dbPassword.trim().equals(encryptedPassword))) {
System.err.println("密码不匹配");
throw new FailedLoginException("密码不匹配");
}
if("0".equals(state)){
throw new FailedLoginException("账号未激活");
}
} catch (IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + "不存在");
}
e.printStackTrace();
throw new FailedLoginException("存在多个相同账号" + username);
} catch (DataAccessException e) {
e.printStackTrace();
throw new PreventedException("sql异常 " + username, e);
}


return createHandlerResult(credential, new SimplePrincipal(username), null);
}


public void setSql(String sql) {
this.sql = sql;
}
}

你可能感兴趣的:(java开发)