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()不能使用,具体原因还不知道。