Java Implementation of Campus Network Automatic Login
Preface
As is well known, many universities’ wireless networks are password-free, replaced instead by a web authentication (portal) method. Users can easily access the network by entering their usernames and passwords, as shown in the figure below (image source: internet):
However, this authentication method has a drawback: frequent disconnections. Manually logging in via the web portal using a username and password is cumbersome, which led to the creation of this software for automatic campus network login.
Principle Explanation
Web authentication is essentially an HTML page used to display to users for entering usernames and passwords. The user’s input is sent to the backend server via a POST request for verification. If the verification passes, access is granted; otherwise, access is denied, similar to most website login mechanisms.
Introduction to the Campus Network Automatic Login Program
1. Program Flow
2. Technologies Used
- GET Request – Used to determine if the computer can access the internet.
- POST Request – Used to send data to the authentication server.
- Swing Window – Used to display prompt messages.
- Properties Configuration File – Used to store user information.
- Socket Communication – Tests connectivity with the authentication server.
- Multithreading – Ensures the window does not appear frozen.
- URL Splitting – Extracts information from the authentication URL.
I. Testing Internet Connectivity with GET Request
This is a built-in Java library that can be used directly.
import java.net.HttpURLConnection;
import java.net.URL;
public class HTTPGet {
public static int testWsdlConnection(String address) throws Exception {
int status = 404;
try {
URL urlObj = new URL(address);
HttpURLConnection oc = (HttpURLConnection) urlObj.openConnection();
oc.setUseCaches(false);
oc.setConnectTimeout(3000);
status = oc.getResponseCode();
if (200 == status) {
// 200 indicates a successful connection to the address.
return status;
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return status;
}
}
II. Sending POST Requests
This requires the httpclient
library, which needs to be added to Maven.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
Basic Usage
Define a sendPOST
function, which can be called directly when needed.
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HTTPPost {
/**
*
* Send a request
* @param url The URL to send
* @param headerMap Request header parameter collection key parameter name, value as parameter value
* @param bodyMap Request parameter collection key parameter name, value as parameter value
*/
public static String sendPost(String url, Map<String,String> headerMap, Map<String,String> bodyMap){
// Create a POST request object
HttpPost post = new HttpPost(url);
try {
// Create a parameter collection
List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
// Add parameters
if (bodyMap!=null){
for (String str:bodyMap.keySet()) {
list.add(new BasicNameValuePair(str, bodyMap.get(str)));
}
}
// Put the parameters into the request object, specifying the format for POST request parameters
post.setEntity(new UrlEncodedFormEntity(list));
if (headerMap!=null){
for (String str:headerMap.keySet()
) {
post.addHeader(str,headerMap.get(str));
}
}
CloseableHttpClient client = HttpClients.createDefault();
// Execute the request and obtain the response
CloseableHttpResponse response = client.execute(post);
// Get the returned entity object
HttpEntity entity = response.getEntity();
// Return content
return EntityUtils.toString(entity, "UTF-8");
} catch (Exception e1) {
e1.printStackTrace();
return "";
}
}
}
Campus Network Login
Based on the sendPOST
function, we need to prepare the URL, headers, and body. These parameters are easily obtainable from the browser’s Developer Tools.
If the browser’s developer tools do not meet your needs, it is recommended to use a professional packet sniffer.
After obtaining everything, we store it in a string and then convert it into the form of Map<String,String>
. Here, we need to use the fastjson
component developed by Alibaba, which also needs to be added to Maven.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.66</version>
</dependency>
The complete code is as follows:
String header = "{\"Cache-Control\": \"max-age=0\", \"Upgrade-Insecure-Requests\": \"1\", \"Origin\": \"\", \"Content-Type\": \"application/x-www-form-urlencoded\", \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44\", \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\", \"Referer\": \"\", \"Accept-Encoding\": \"gzip, deflate\", \"Accept-Language\": \"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\", \"Connection\": \"close\"}";
Map<String, String> mapheader = JSONObject.parseObject(header, new TypeReference<Map<String, String>>(){});
Map<String, String> params = new HashMap<String, String>(){{
put("R1", "0");
}};
// Add username and password to params
params.put("DDDDD", name);
params.put("upass", b64.decode2(passwd));
String htmlStr = HTTPPost.sendPost(Path.trim(), mapheader, params);
Java Web Crawler
After sending the POST request, we need to determine if the login was successful. Since our university’s login response is not a JSON list but an HTML file, the most significant feature is the page title: Authentication Successful Page
. We need to use this title to determine if the login was successful, so we need to use Java’s web crawling capabilities.
Document doc = Jsoup.parse(htmlStr);
String e_title = doc.title();
return Objects.equals(e_title, "认证成功页");
There is a major pitfall here: string comparison using e_title == "Authentication Successful Page"
does not work no matter how hard you try. Later, after asking our teacher, we learned about Java’s string comparison methods.
III. Reading Configuration Files
Here, we use Java’s properties
configuration file, where both the username and password are stored.
Reading
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class ReadPropertise {
private static Properties properties = new Properties();
private static BufferedInputStream in;
public static void Readin() throws Exception{
try {
in = new BufferedInputStream(new FileInputStream("c.properties"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
try {
properties.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// Read the username and password values
public static List getUser(){
String name = properties.getProperty("name");
String passwd = properties.getProperty("password");
List map = new ArrayList();
map.add(name);
map.add(passwd);
return map;
}
}
Writing
Retrieve data from the Swing window’s input fields and write it to the properties file.
Properties properties = new Properties();
properties.setProperty("name", name);
properties.setProperty("password", passwd);
try {
properties.store(new FileWriter("c.properties"), null);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
Swing Window Framework
Swing is a windowing module in Java, also built-in, and will be explained using comments below.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
public class LoginSwing {
public void placeComponents() {
// Create a window
JFrame frame = new JFrame("Login");//Login is the window title
// Set window size
frame.setSize(350, 200);
// Window style
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create a panel
JPanel panel = new JPanel();
// Username prompt
JLabel userLabel = new JLabel("Username:");
// Set label position absolutely
userLabel.setBounds(10, 20, 60, 25);
// Add label to panel
panel.add(userLabel);
// Username input field
JTextField userText = new JTextField(20);
userText.setBounds(65, 20, 165, 25);
panel.add(userText);
// Password prompt
JLabel passwordLabel = new JLabel("Password:");
passwordLabel.setBounds(10, 50, 60, 25);
panel.add(passwordLabel);
// Password input field, hides input content
JPasswordField passwordText = new JPasswordField(20);
passwordText.setBounds(65, 50, 165, 25);
panel.add(passwordText);
// Create a label for the address
JLabel addLabel = new JLabel("Address:");
addLabel.setBounds(10, 80, 60, 25);
panel.add(addLabel);
// Create an address input field
JTextField addText = new JTextField(20);
addText.setBounds(65, 80, 165, 25);
panel.add(addText);
// Create a label for prompt messages
JLabel noticeLabel = new JLabel();
noticeLabel.setForeground(Color.red);
noticeLabel.setBounds(95, 110, 90, 25);
panel.add(noticeLabel);
// Create a login button
JButton loginButton = new JButton("Login");
loginButton.setBounds(10, 110, 80, 25);
panel.add(loginButton);
// Button click event
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String name = userText.getText().trim();//Retrieve content from input field, trim removes spaces
String passwd = String.valueOf(passwordText.getPassword());
String host = addText.getText().trim();
if ("".equals(name)) {
noticeLabel.setText("Please enter a username!");
} else if ("".equals(passwd)) {
noticeLabel.setText("Please enter a password!");
} else if ("".equals(host)) {
noticeLabel.setText("Please enter an address!");
} else {
// Execute statements
// Modify label content
noticeLabel.setText("Login successful");
// Close window
frame.dispose();
}
}
});
// Add panel to window
frame.add(panel);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
panel.setLayout(null);
// Display window
frame.setVisible(true);
}
}
Socket Testing
Before logging in, we should check if the campus network’s authentication server is working. This also uses Java’s built-in library.
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
public class SocketTest {
// Determine if IP and port are connectable
public static boolean isHostConnectable(String host, int port) {
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(host, port));
} catch (IOException e) {
//e.printStackTrace();
return false;
} finally {
try {
socket.close();
} catch (IOException e) {
//e.printStackTrace();
}
}
return true;
}
}
Java Multithreading Usage
Basic Usage
new Thread(new Runnable() {
@Override
public void run() {
}
}.start()
Example: Sleep Sorting
public class Main {
public static void main(String[] args) {
int[] nums = new int[]{235, 233, 110, 789, 5, 0, 1};
for (int item : nums) {
new Thread(() -> {
try {
Thread.sleep(item);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(item);
}).start();
}
}
}
Do not use this in production environments. This code is so complex that it’s hard to think of without a brain hemorrhage. The problems exposed by sleep sorting are also obvious:
- It cannot sleep for negative numbers.
- There is an error between similar numbers.
- If you give it a very large number to sleep, it might not even be cured from a brain hemorrhage.
Download
Download link 1:
Link: https://pan.baidu.com/s/1TnHwBci5RD_67hNRG8XSUQ
Extract code: afi7