1.原理:
用户在发起登录请求,把自己的用户名和密码传到后台,后台使用httpclient进行模拟登录
登录成功后,CAS服务器会给httpclient发一个cookie(TGT,ticket granting ticket),
服务器会把这个cookie返回给用户,完成一次模拟登录的过程。
2.核心代码:
package ecen.mip.sys.action;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.stereotype.Component;
@Namespace("/")
@Action("sysSingleSignOnAction")
@Component("sysSingleSignOnAction")
@Results({ @Result(name = "SUCCESS", location = "/sys/sys_new_index.jsp") })
public class SysSingleSignOnAction extends BaseAction {
private static final long serialVersionUID = -2096730223578871319L;
private static final Logger log = Logger.getLogger(SysSingleSignOnAction.class);
final String server = "http://192.168.0.142:8080/cas/login";
private String username;
private String password;
@Override
public String execute() throws Exception {
Cookie cookie = getTicketGrantingTicket(server, username, password);
if(cookie!=null){
getResponse().addCookie(convertToServletCookie(cookie));
log.info("The user authenticated successfully whose nickname code is "+username+" ! ");
return "SUCCESS";
}
return super.execute();
}
private Cookie getTicketGrantingTicket(final String server,final String username, final String password) throws IOException {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(server);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("username", username));
nvps.add(new BasicNameValuePair("password", password));
nvps.add(new BasicNameValuePair("lt", doCasLoginRequest(client, server)));
nvps.add(new BasicNameValuePair("_eventId", "submit"));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
try {
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
if(entity!=null){
Cookie cookie = getCookieValue(client, "CASTGC");
entity.consumeContent();
return cookie;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Cookie getCookieValue(DefaultHttpClient httpclient, String name) {
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
return null;
} else {
for (int i = 0; i < cookies.size(); i++) {
Cookie cookie = cookies.get(i);
if (cookie.getName().equalsIgnoreCase(name)) {
return cookie;
}
}
}
return null;
}
private String doCasLoginRequest(DefaultHttpClient httpclient, String url) throws IOException {
String result = "";
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
BufferedReader rd = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
String tempLine = rd.readLine();
String s = "<input type=\"hidden\" name=\"lt\" value=\"";
while (tempLine != null){
int index = tempLine.indexOf(s);
if(index != -1) {
String s1 = tempLine.substring(index + s.length());
int index1 = s1.indexOf("\"");
if(index1 != -1)
result = s1.substring(0, index1);
}
tempLine = rd.readLine();
}
if (entity != null) {
entity.consumeContent();
}
return result;
}
private javax.servlet.http.Cookie convertToServletCookie(Cookie cookie){
javax.servlet.http.Cookie retCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
retCookie.setComment(cookie.getComment());
retCookie.setDomain(cookie.getDomain());
retCookie.setHttpOnly(false);
retCookie.setSecure(false);
retCookie.setPath(cookie.getPath());
retCookie.setVersion(cookie.getVersion());
retCookie.setMaxAge((int) ((cookie.getExpiryDate().getTime()-System.currentTimeMillis())/1000));
return retCookie;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
写完就贴上来了,所以没写注释,不过,应该都能看懂吧
3.注意事项:通过这种途径登录后,request.getRemoteUser()不能使用,具体原因还不知道。