1.原理:
用户在发起登录请求,把自己的用户名和密码传到后台,后台使用httpclient进行模拟登录
登录成功后,CAS服务器会给httpclient发一个cookie(TGT,ticket granting ticket),
服务器会把这个cookie返回给用户,完成一次模拟登录的过程。
2.核心代码:
001 |
package ecen.mip.sys.action;
|
003 |
import java.io.BufferedReader;
|
004 |
import java.io.IOException;
|
005 |
import java.io.InputStreamReader;
|
006 |
import java.util.ArrayList;
|
007 |
import java.util.List;
|
009 |
import org.apache.http.HttpEntity;
|
010 |
import org.apache.http.HttpResponse;
|
011 |
import org.apache.http.NameValuePair;
|
012 |
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
013 |
import org.apache.http.client.methods.HttpGet;
|
014 |
import org.apache.http.client.methods.HttpPost;
|
015 |
import org.apache.http.cookie.Cookie;
|
016 |
import org.apache.http.impl.client.DefaultHttpClient;
|
017 |
import org.apache.http.message.BasicNameValuePair;
|
018 |
import org.apache.http.protocol.HTTP;
|
019 |
import org.apache.log4j.Logger;
|
020 |
import org.apache.struts2.convention.annotation.Action;
|
021 |
import org.apache.struts2.convention.annotation.Namespace;
|
022 |
import org.apache.struts2.convention.annotation.Result;
|
023 |
import org.apache.struts2.convention.annotation.Results;
|
024 |
import org.springframework.stereotype.Component;
|
027 |
@Action ( "sysSingleSignOnAction" )
|
028 |
@Component ( "sysSingleSignOnAction" )
|
029 |
@Results ({ @Result (name = "SUCCESS" , location = "/sys/sys_new_index.jsp" ) })
|
030 |
public class SysSingleSignOnAction extends BaseAction {
|
032 |
private static final long serialVersionUID = -2096730223578871319L;
|
033 |
private static final Logger log = Logger.getLogger(SysSingleSignOnAction. class );
|
034 |
final String server = "http://192.168.0.142:8080/cas/login" ;
|
035 |
private String username;
|
036 |
private String password;
|
039 |
public String execute() throws Exception {
|
040 |
Cookie cookie = getTicketGrantingTicket(server, username, password);
|
042 |
getResponse().addCookie(convertToServletCookie(cookie));
|
043 |
log.info( "The user authenticated successfully whose nickname code is " +username+ " ! " );
|
046 |
return super .execute();
|
050 |
private Cookie getTicketGrantingTicket( final String server, final String username, final String password) throws IOException {
|
051 |
DefaultHttpClient client = new DefaultHttpClient();
|
052 |
HttpPost post = new HttpPost(server);
|
054 |
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
|
055 |
nvps.add( new BasicNameValuePair( "username" , username));
|
056 |
nvps.add( new BasicNameValuePair( "password" , password));
|
057 |
nvps.add( new BasicNameValuePair( "lt" , doCasLoginRequest(client, server)));
|
058 |
nvps.add( new BasicNameValuePair( "_eventId" , "submit" ));
|
059 |
post.setEntity( new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
|
061 |
HttpResponse response = client.execute(post);
|
062 |
HttpEntity entity = response.getEntity();
|
064 |
Cookie cookie = getCookieValue(client, "CASTGC" );
|
065 |
entity.consumeContent();
|
068 |
} catch (Exception e) {
|
075 |
private Cookie getCookieValue(DefaultHttpClient httpclient, String name) {
|
076 |
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
|
077 |
if (cookies.isEmpty()) {
|
080 |
for ( int i = 0 ; i < cookies.size(); i++) {
|
081 |
Cookie cookie = cookies.get(i);
|
082 |
if (cookie.getName().equalsIgnoreCase(name)) {
|
091 |
private String doCasLoginRequest(DefaultHttpClient httpclient, String url) throws IOException {
|
093 |
HttpGet httpget = new HttpGet(url);
|
094 |
HttpResponse response = httpclient.execute(httpget);
|
095 |
HttpEntity entity = response.getEntity();
|
096 |
BufferedReader rd = new BufferedReader( new InputStreamReader(entity.getContent(), "UTF-8" ));
|
097 |
String tempLine = rd.readLine();
|
098 |
String s = "<input type=\"hidden\" name=\"lt\" value=\"" ;
|
099 |
while (tempLine != null ){
|
100 |
int index = tempLine.indexOf(s);
|
102 |
String s1 = tempLine.substring(index + s.length());
|
103 |
int index1 = s1.indexOf( "\"" );
|
105 |
result = s1.substring( 0 , index1);
|
107 |
tempLine = rd.readLine();
|
109 |
if (entity != null ) {
|
110 |
entity.consumeContent();
|
116 |
private javax.servlet.http.Cookie convertToServletCookie(Cookie cookie){
|
117 |
javax.servlet.http.Cookie retCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
|
118 |
retCookie.setComment(cookie.getComment());
|
119 |
retCookie.setDomain(cookie.getDomain());
|
120 |
retCookie.setHttpOnly( false );
|
121 |
retCookie.setSecure( false );
|
122 |
retCookie.setPath(cookie.getPath());
|
123 |
retCookie.setVersion(cookie.getVersion());
|
124 |
retCookie.setMaxAge(( int ) ((cookie.getExpiryDate().getTime()-System.currentTimeMillis())/ 1000 ));
|
128 |
public String getUsername() {
|
132 |
public void setUsername(String username) {
|
133 |
this .username = username;
|
136 |
public String getPassword() {
|
140 |
public void setPassword(String password) {
|
141 |
this .password = password;
|
写完就贴上来了,所以没写注释,不过,应该都能看懂吧
3.注意事项:
通过这种途径登录后,request.getRemoteUser()不能使用,具体原因还不知道。