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; |
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 class JwcLogin { |
||||||
public String getLoginCookie(String user, String password) { |
// 默认5秒超时
|
||||||
return ""; |
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