parent
e03fb17395
commit
4bb358cc05
@ -0,0 +1,15 @@ |
||||
package cn.linghang.mywust.core.api; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
@Getter |
||||
public class JwcApiUrl { |
||||
/** |
||||
* 统一认证登录验证的api地址,请求之后可进一步获取ticket |
||||
*/ |
||||
public static final String UNION_AUTH_API = "https://auth.wust.edu.cn/lyuapServer/v1/tickets"; |
||||
|
||||
public static final String JWC_SSO_SERVICE = "http://bkjx.wust.edu.cn/jsxsd/sso.jsp"; |
||||
public static final String JWC_TICKET_API = "http://bkjx.wust.edu.cn/jsxsd/sso.jsp?ticket=%s"; |
||||
|
||||
} |
@ -0,0 +1,4 @@ |
||||
package cn.linghang.mywust.core.exception; |
||||
|
||||
public class BasicException extends Exception { |
||||
} |
@ -0,0 +1,4 @@ |
||||
package cn.linghang.mywust.core.exception; |
||||
|
||||
public class PasswordWornException extends BasicException { |
||||
} |
@ -0,0 +1,41 @@ |
||||
package cn.linghang.mywust.core.service.undergraduate; |
||||
|
||||
import cn.linghang.mywust.network.HttpRequest; |
||||
import cn.linghang.mywust.util.StringUtil; |
||||
|
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class AuthRequestGenerator { |
||||
public static HttpRequest unionLoginTGTRequest(String username, String password, String service) { |
||||
Map<String, String> requestForm = new HashMap<>(); |
||||
requestForm.put("username", username); |
||||
requestForm.put("password", password); |
||||
requestForm.put("service", service); |
||||
requestForm.put("loginType", ""); |
||||
|
||||
String queryString = StringUtil.generateQueryString(requestForm); |
||||
|
||||
HttpRequest request = new HttpRequest(); |
||||
request.setData(queryString.getBytes(StandardCharsets.UTF_8)); |
||||
|
||||
return request; |
||||
} |
||||
|
||||
public static HttpRequest loginTicketRequest(String service) { |
||||
Map<String, String> requestForm = new HashMap<>(); |
||||
requestForm.put("service", service); |
||||
|
||||
String queryString = StringUtil.generateQueryString(requestForm); |
||||
|
||||
HttpRequest request = new HttpRequest(); |
||||
request.setData(queryString.getBytes(StandardCharsets.UTF_8)); |
||||
|
||||
return request; |
||||
} |
||||
|
||||
public static HttpRequest sessionCookieRequest() { |
||||
return new HttpRequest(); |
||||
} |
||||
} |
@ -1,7 +1,65 @@ |
||||
package cn.linghang.mywust.core.service.undergraduate; |
||||
|
||||
import cn.linghang.mywust.core.api.JwcApiUrl; |
||||
import cn.linghang.mywust.core.exception.BasicException; |
||||
import cn.linghang.mywust.core.exception.PasswordWornException; |
||||
import cn.linghang.mywust.network.HttpRequest; |
||||
import cn.linghang.mywust.network.HttpResponse; |
||||
import cn.linghang.mywust.network.RequestClientOption; |
||||
import cn.linghang.mywust.network.Requester; |
||||
|
||||
import java.io.IOException; |
||||
import java.net.URL; |
||||
|
||||
public class JwcLogin { |
||||
public String getLoginCookie(String user, String password) { |
||||
return ""; |
||||
// 默认5秒超时
|
||||
private static final int DEFAULT_TIMEOUT = 5; |
||||
|
||||
private final Requester requester; |
||||
|
||||
public JwcLogin(Requester requester) { |
||||
this.requester = requester; |
||||
} |
||||
|
||||
public String getLoginCookie(String username, String password, RequestClientOption requestOption) throws IOException, BasicException { |
||||
// 获取ticket granting ticket(TGT)
|
||||
HttpRequest TGTRequest = AuthRequestGenerator.unionLoginTGTRequest(username, password, JwcApiUrl.JWC_SSO_SERVICE); |
||||
|
||||
HttpResponse unionAuthResponse = requester.post(new URL(JwcApiUrl.UNION_AUTH_API), TGTRequest, requestOption); |
||||
|
||||
String redirectAddress = unionAuthResponse.getHeaders().get("Location"); |
||||
if (redirectAddress == null) { |
||||
throw new PasswordWornException(); |
||||
} |
||||
|
||||
// 获取服务ticket(service ticket,st)
|
||||
HttpRequest serviceTicketRequest = AuthRequestGenerator.loginTicketRequest(JwcApiUrl.JWC_SSO_SERVICE); |
||||
|
||||
HttpResponse serviceTicketResponse = |
||||
requester.post(new URL(redirectAddress.replace("http:", "https:")), serviceTicketRequest, requestOption); |
||||
|
||||
byte[] serviceTicketResponseData = serviceTicketResponse.getBody(); |
||||
if (serviceTicketResponseData == null) { |
||||
System.err.println("获取服务st出错,serviceTicketResponseData == null"); |
||||
throw new BasicException(); |
||||
} |
||||
String serviceTicket = new String(serviceTicketResponseData); |
||||
|
||||
// 获取登录cookie(session)
|
||||
HttpRequest sessionRequest = AuthRequestGenerator.sessionCookieRequest(); |
||||
HttpResponse sessionResponse = requester.get(new URL(String.format(JwcApiUrl.JWC_TICKET_API, serviceTicket)), sessionRequest, requestOption); |
||||
|
||||
String cookies = sessionResponse.getCookies(); |
||||
if (cookies == null || !cookies.contains("JSESSIONID") || !cookies.contains("SERVERID")) { |
||||
System.err.println("获取服务session cookie出错,关键Cookie缺失"); |
||||
System.err.println("Cookies: " + cookies); |
||||
throw new BasicException(); |
||||
} |
||||
|
||||
return cookies; |
||||
} |
||||
|
||||
private void getLoginGTG(String username, String password) { |
||||
|
||||
} |
||||
} |
||||
|
@ -0,0 +1,59 @@ |
||||
package cn.linghang.mywust.network.okhttp; |
||||
|
||||
import javax.net.ssl.*; |
||||
import java.security.KeyStore; |
||||
import java.security.SecureRandom; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.Arrays; |
||||
|
||||
public class TrustAllCert { |
||||
public static SSLSocketFactory getSSLSocketFactory() { |
||||
try { |
||||
SSLContext sslContext = SSLContext.getInstance("SSL"); |
||||
sslContext.init(null, getTrustManager(), new SecureRandom()); |
||||
return sslContext.getSocketFactory(); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
private static TrustManager[] getTrustManager() { |
||||
return new TrustManager[]{ |
||||
new X509TrustManager() { |
||||
@Override |
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) { |
||||
} |
||||
|
||||
@Override |
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) { |
||||
} |
||||
|
||||
@Override |
||||
public X509Certificate[] getAcceptedIssuers() { |
||||
return new X509Certificate[]{}; |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
public static HostnameVerifier getHostnameVerifier() { |
||||
return (s, sslSession) -> true; |
||||
} |
||||
|
||||
public static X509TrustManager getX509TrustManager() { |
||||
X509TrustManager trustManager = null; |
||||
try { |
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
||||
trustManagerFactory.init((KeyStore) null); |
||||
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); |
||||
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { |
||||
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers)); |
||||
} |
||||
trustManager = (X509TrustManager) trustManagers[0]; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
return trustManager; |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>cn.linghang</groupId> |
||||
<artifactId>mywust-test</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>cn.linghang</groupId> |
||||
<artifactId>mywust-core</artifactId> |
||||
<version>0.0.1-dev</version> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>cn.linghang</groupId> |
||||
<artifactId>mywust-network-okhttp</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>11</maven.compiler.source> |
||||
<maven.compiler.target>11</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
</project> |
@ -0,0 +1,39 @@ |
||||
import cn.linghang.mywust.core.exception.BasicException; |
||||
import cn.linghang.mywust.core.service.undergraduate.JwcLogin; |
||||
import cn.linghang.mywust.network.RequestClientOption; |
||||
import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; |
||||
import cn.linghang.mywust.util.PasswordEncoder; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Scanner; |
||||
|
||||
public class JwcLoginTest { |
||||
public static void main(String[] args) throws BasicException, IOException { |
||||
new JwcLoginTest().run(); |
||||
} |
||||
|
||||
private void run() throws BasicException, IOException { |
||||
System.out.println("输入账号(学号)和密码,用“ ”(空格)分割"); |
||||
|
||||
Scanner scanner = new Scanner(System.in); |
||||
|
||||
String input = scanner.nextLine(); |
||||
|
||||
String username = input.split(" ")[0]; |
||||
String password = input.split(" ")[1]; |
||||
|
||||
System.out.println("账号:" + username); |
||||
System.out.println("密码:" + password); |
||||
|
||||
JwcLogin jwcLogin = new JwcLogin(new SimpleOkhttpRequester()); |
||||
|
||||
RequestClientOption option = new RequestClientOption(); |
||||
option.setTimeout(5); |
||||
option.setProxy(null); |
||||
option.setFallowUrlRedirect(false); |
||||
|
||||
String cookies = jwcLogin.getLoginCookie(username, PasswordEncoder.encodePassword(password), option); |
||||
|
||||
System.out.println(cookies); |
||||
} |
||||
} |
@ -0,0 +1,37 @@ |
||||
package cn.linghang.mywust.util; |
||||
|
||||
import com.google.common.base.Joiner; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
public class StringUtil { |
||||
/** |
||||
* 将map转换成url请求表单格式的请求字符串(类似于 user=admin&passwd=123456&time=11111 这种) |
||||
* |
||||
* @param queryParams 请求参数 |
||||
* @return 生成的表单请求字符串 |
||||
*/ |
||||
public static String generateQueryString(Map<String, String> queryParams) { |
||||
return Joiner.on('&') |
||||
.useForNull("") |
||||
.withKeyValueSeparator('=') |
||||
.join(queryParams); |
||||
} |
||||
|
||||
/** |
||||
* 解析服务器相应的Set-Cookie的header值,并拼成能够直接用于Cookie的header值 |
||||
* |
||||
* @param cookieHeaders 服务器响应的Set-Cookie |
||||
* @return 解析后可用的Cookie |
||||
*/ |
||||
public static String parseCookie(List<String> cookieHeaders) { |
||||
List<String> allCookies = new ArrayList<>(cookieHeaders.size()); |
||||
cookieHeaders.forEach((cookieHeader) -> allCookies.add(cookieHeader.split(";")[0])); |
||||
|
||||
return Joiner.on(';') |
||||
.useForNull("") |
||||
.join(allCookies); |
||||
} |
||||
} |
Loading…
Reference in new issue