单点登录【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。

相关推荐
皙然7 分钟前
深入理解 Java HashMap:从底层原理、源码设计到面试考点全解析
java·开发语言·面试
元Y亨H12 分钟前
RuoYi-Cloud-Vue 架构全解析:微服务+前后端分离
java·微服务
子超兄12 分钟前
ThreadLocal相关问题
java
啊唯不困39 分钟前
AI智能应用开发(Java)起点-终点 -1、java的前世今生andJava环境配置、jdk下载,以及Idea下载和基本应用
java·开发语言·intellij-idea
_muffinman41 分钟前
Java学习笔记-第2章 运算和语句
java·笔记·学习
荒夜长歌43 分钟前
传统java行业跳槽面试汇总(后续会更新)
java·面试·跳槽
旷世奇才李先生43 分钟前
065智慧农业专家远程指导系统-springboot+vue
java·vue.js·spring boot
大迪deblog44 分钟前
系统架构设计-软件架构风格
java·开发语言·架构·软件构建
盐水冰1 小时前
【烘焙坊项目】后端搭建(10) - 地址簿功能&用户下单&微信支付
java·数据库·后端
重庆小透明1 小时前
【面试问题】java小厂
java·开发语言·面试