单点登录【demo】

前言

2023-07-29 15:44:56

公开发布于

2024-5-22 00:04:56

单点登录【demo】

以下是 Java 实现单点登录的示例代码:

单点登录(Single Sign-On,SSO)是一种身份认证和授权机制,可以使用户在多个应用程序或系统之间使用相同的身份进行登录。以下是一个简单的单点登录实现的示例代码:

认证服务器:

java 复制代码
import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class AuthServer {

    private Map<String, String> users = new HashMap<>();    // 保存用户信息

    public static void main(String[] args) {
        SpringApplication.run(AuthServer.class, args);
    }

    @PostMapping("/authenticate")
    public ResponseEntity<String> authenticate(@RequestBody User user) {
        if (users.containsKey(user.getUsername()) && users.get(user.getUsername()).equals(user.getPassword())) {
            String token = generateToken(); // 生成令牌
            TokenStore.addToken(token, user.getUsername()); // 将令牌保存到TokenStore
            return ResponseEntity.ok(token);
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
    }

    private String generateToken() {
        // 生成令牌的代码
        return "token123";
    }

    static class User {
        private String username;
        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }
}

Token 存储:

java 复制代码
import java.util.HashMap;
import java.util.Map;

public class TokenStore {

    private static Map<String, String> tokens = new HashMap<>(); // 保存Token和对应的用户名

    public static void addToken(String token, String username) { // 将Token和对应的用户名保存到Map中
        tokens.put(token, username);
    }

    public static boolean isValidToken(String token) { // 判断Token是否有效
        return tokens.containsKey(token);
    }

    public static String getUsername(String token) { // 根据Token获取对应的用户名
        return tokens.get(token);
    }

    public static void removeToken(String token) { // 删除Token
        tokens.remove(token);
    }
}

客户端:

java 复制代码
import java.util.Scanner;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class Client {

    private static String authServerUrl = "http://localhost:8080/authenticate"; // 认证服务器URL

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Username: ");
        String username = scanner.nextLine();
        System.out.print("Password: ");
        String password = scanner.nextLine();
        scanner.close();

        // 发送认证请求
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        HttpEntity<?> requestEntity = new HttpEntity<>(new AuthServer.User(username, password), headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(authServerUrl, HttpMethod.POST, requestEntity, String.class);

        if (responseEntity.getStatusCode() == HttpStatus.OK) { // 如果认证成功
            String token = responseEntity.getBody(); // 获取令牌
            System.out.println("Token: " + token);

            // 访问受保护资源
            String resourceUrl = "http://localhost:8081/resource";
            headers.set("Authorization", "Bearer " + token);
            requestEntity = new HttpEntity<>(null, headers);
            responseEntity = restTemplate.exchange(resourceUrl, HttpMethod.GET, requestEntity, String.class);
            System.out.println(responseEntity.getBody()); // 输出受保护资源的内容

            // 注销
            String logoutUrl = "http://localhost:8080/logout";
            headers.set("Content-Type", "application/x-www-form-urlencoded");
            requestEntity = new HttpEntity<>("token=" + token, headers);
            responseEntity = restTemplate.exchange(logoutUrl, HttpMethod.POST, requestEntity, String.class);
            System.out.println(responseEntity.getBody()); // 输出注销消息
        } else { // 如果认证失败
            System.out.println("Invalid username or password");
        }
    }
}

在这个例子中,客户端会向认证服务器发送一个 POST 请求以验证用户身份。如果验证通过,则认证服务器将返回一个 Token,客户端存储并在后续的请求中使用该 Token。在此示例中,客户端还会尝试访问受保护的资源,该资源要求使用令牌进行身份验证。

另外,Token Store 是一个用于存储 Token 和对应用户名的简单 Map 实现,用于在服务器和客户端之间共享 Token。

相关推荐
lUie INGA2 小时前
在2023idea中如何创建SpringBoot
java·spring boot·后端
geBR OTTE2 小时前
SpringBoot中整合ONLYOFFICE在线编辑
java·spring boot·后端
Porunarufu3 小时前
博客系统UI自动化测试报告
java
Aurorar0rua4 小时前
CS50 x 2024 Notes C - 05
java·c语言·数据结构
Cosmoshhhyyy4 小时前
《Effective Java》解读第49条:检查参数的有效性
java·开发语言
布谷歌4 小时前
常见的OOM错误 ( OutOfMemoryError全类型详解)
java·开发语言
eLIN TECE5 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
老神在在0015 小时前
Spring Bean 的六种作用域详解
java·后端·spring
仙草不加料5 小时前
互联网大厂Java面试故事实录:三轮场景化技术提问与详细答案解析
java·spring boot·微服务·面试·aigc·电商·内容社区
程序员老邢5 小时前
【技术底稿 19】Redis7 集群密码配置 + 权限锁死 + 磁盘占满连锁故障真实排查全记录
java·服务器·经验分享·redis·程序人生·微服务