构造CAS客户端的登录Servlet

根据CAS客户端的Filter我们可以改造出一个具有同样验证功能的Servlet出来,改造后的代码如下:

public class CasLogin extends HttpServlet {
//*********************************************************************
// Constants
public final static String CAS_FILTER_USER = "edu.yale.its.tp.cas.client.filter.user";

/** Session attribute in which the username is stored */
private ServletConfig config;
private String casLogin,casValidate,casAuthorizedProxy,casServiceUrl,casRenew,casServerName;
private String redirectURL;
private String desktopURL;
private AuthHandler handler;


public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
try {
// create an instance of the right authentication handler
String handlerName =config.getInitParameter("com.longshine.sso.cas.authHandler");
if (handlerName == null)
throw new ServletException(" [启动异常] 参数 com.longshine.sso.cas.authHandler 搜索失败!");
handler = (AuthHandler) Class.forName(handlerName).newInstance();
if (!(handler instanceof TrustHandler)){
throw new ServletException("unrecognized handler type: " + handlerName);
}else{
String suc = config.getInitParameter("edu.yale.its.tp.cas.casLoginSuccessCode");
AuthCodeRepository.updateSucCode(Integer.parseInt(suc),handler);
}
} catch (InstantiationException ex) {
throw new ServletException(ex.toString());
} catch (ClassNotFoundException ex) {
throw new ServletException(ex.toString());
} catch (IllegalAccessException ex) {
throw new ServletException(ex.toString());
}
//retrieve a relative URL for the CasLogin Servlet
this.casLogin = config.getInitParameter("edu.yale.its.tp.cas.casLogin");
this.casValidate = config.getInitParameter("edu.yale.its.tp.cas.casValidate");
this.casServerName = config.getInitParameter("edu.yale.its.tp.cas.serverName");
this.casServiceUrl = config.getInitParameter("edu.yale.its.tp.cas.client.filter.serviceUrl");
this.casAuthorizedProxy = config.getInitParameter("edu.yale.its.tp.cas.client.filter.authorizedProxy");
this.casRenew = config.getInitParameter("edu.yale.its.tp.cas.client.filter.renew");
this.redirectURL = config.getInitParameter("edu.yale.its.tp.cas.redirectURL");
this.desktopURL = config.getInitParameter("edu.yale.its.tp.cas.desktopURL");
if (casLogin == null || casValidate == null ||
casServerName == null || redirectURL == null ||
desktopURL == null)
throw new ServletException("[启动异常] 请配置如下必要参数: edu.yale.its.tp.cas.casLogin, "
+ "-casValidate, -serverName, -redirectURL, and -desktopURL ");
}

// *********************************************************************
// Request handling

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

//avoid caching (in the stupidly numerous ways we must)
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control","no-store");
response.setDateHeader("Expires",-1);
HttpSession session = request.getSession();

// if our attribute's already present, don't do anything
if (session != null && session.getAttribute(CAS_FILTER_USER) != null) {
String username = session.getAttribute(CAS_FILTER_USER).toString();
//使用CAS用户登录本地系统
loginToClientService(request,response,username);
return;
}

// otherwise, we need to authenticate via CAS
String ticket = request.getParameter("ticket");

// no ticket? abort request processing and redirect
if (ticket == null || ticket.equals("")) {
if (casLogin == null) {
throw new ServletException(
"When CASFilter protects pages that do not receive a 'ticket' "
+ "parameter, it needs a edu.yale.its.tp.cas.client.filter.loginUrl "
+ "filter parameter");
}
response.sendRedirect(
casLogin
+ "?service="
+ getService(request)
+ ((casRenew != null && !casRenew.equals(""))
? "&renew=" + casRenew
: ""));
return;
}

// Yay, ticket! Validate it.
String user = getAuthenticatedUser(request);
if (user == null)
throw new ServletException("Unexpected CAS authentication error");
// Store the authenticated user in the session
if (session != null) // probably unncessary
{
session.setAttribute(CAS_FILTER_USER, user);
//使用CAS用户登录本地系统
loginToClientService(request,response,user);
}

}

// *********************************************************************
// Utility methods

/**
* 使用CAS服务器验证过的安全用户名登录CAS 客户端系统
* @param request
* @param response
* @param username 用户名
* @throws IOException
* @throws ServletException
*/
private void loginToClientService(HttpServletRequest request,
HttpServletResponse response, String username)
throws IOException,ServletException{
/*
//判断用户在本地系统是否存在
if(username == null || username.equals("") || username.trim().length()==0){
response.sendRedirect(redirectURL);
}
else if (((TrustHandler)handler).findUserByName(request, username)){
//根据用户名自动执行登录动作
((TrustHandler)handler).autoLoginWithUsername(request, response, username);
//登录成功后转向工作桌面
request.getRequestDispatcher(desktopURL).forward(request,response);
}
else{
response.sendRedirect(redirectURL);
}*/
//HttpSession session = request.getSession();
TrustHandler tHandler = (TrustHandler)handler;
String fail = "errCode=";
int code = tHandler.loginWithUsername(request, response, username);
if (code == AuthCodeRepository.getSucCode()){
//登录成功后转向工作桌面
String module = request.getQueryString();//取后缀参数
//response.sendRedirect("登录成功页面(success)");
/*
if(session != null){
session.setAttribute("username", username);
}*/
//request.getRequestDispatcher(desktopURL).forward(request,response);
response.sendRedirect(desktopURL+"?"+module);
}else{
//登录失败后根据错误编码转向错误页面
fail += Integer.toString(code);
//response.sendRedirect("登录失败页面(fail)");
response.sendRedirect(redirectURL+"?"+fail);
}
}

/**
* Converts a ticket parameter to a username, taking into account an
* optionally configured trusted proxy in the tier immediately in front
* of us.
*/
private String getAuthenticatedUser(HttpServletRequest request)
throws ServletException {
ProxyTicketValidator pv = null;
//String SaxParserFactory = System.getProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
//String DocumentBuilderFactory = System.getProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
//String TransformaerFactory = System.getProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");

//System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
//System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
//System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
try {
//System.out.println("CAS 开始验证 ticket ==========================");
pv = new ProxyTicketValidator();
pv.setCasValidateUrl(casValidate);
pv.setServiceTicket(request.getParameter("ticket"));
pv.setService(getService(request));
pv.setRenew(Boolean.valueOf(casRenew).booleanValue());
pv.validate();
//System.out.println("CAS 验证完毕 ticket ==========================");
if (!pv.isAuthenticationSuccesful())
throw new ServletException(
"CAS authentication error: " + pv.getErrorCode() + ": " + pv.getErrorMessage());
if (pv.getProxyList().size() != 0) {
// ticket was proxied
if (casAuthorizedProxy == null) {
throw new ServletException("this page does not accept proxied tickets");
} else {
boolean authorized = false;
String proxy = (String)pv.getProxyList().get(0);
StringTokenizer casProxies =
new StringTokenizer(casAuthorizedProxy);
while (casProxies.hasMoreTokens()) {
if (proxy.equals(casProxies.nextToken())) {
authorized = true;
break;
}
}
if (!authorized) {
throw new ServletException(
"unauthorized top-level proxy: '"
+ pv.getProxyList().get(0)
+ "'");
}
}
}
return pv.getUser();
} catch (SAXException ex) {
String xmlResponse = "";
if (pv != null)
xmlResponse = pv.getResponse();
throw new ServletException(ex + " " + xmlResponse);
} catch (ParserConfigurationException ex) {
throw new ServletException(ex);
} catch (IOException ex) {
throw new ServletException(ex);
}
}

/**
* Returns either the configured service or figures it out for the current
* request. The returned service is URL-encoded.
*/
private String getService(HttpServletRequest request)
throws ServletException {
// ensure we have a server name or service name
if (casServerName == null && casServiceUrl == null)
throw new ServletException(
"need one of the following configuration "
+ "parameters: edu.yale.its.tp.cas.client.filter.serviceUrl or "
+ "edu.yale.its.tp.cas.client.filter.serverName");

// use the given string if it's provided
if (casServiceUrl != null)
return URLEncoder.encode(casServiceUrl);
else
// otherwise, return our best guess at the service
return Util.getService(request, casServerName);
}
}

另外我们仅需要配置一个具有.loginWithUsername(request, response, username);函数的接口,及此Servlet的启动相关参数就可以实现一个Servlet形式的登录入口,这样我们在保留此应用原有登录入口的条件下可以增加CAS的SSO功能,不影响原有系统的使用,对原有系统也无需做过多的改动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值