優れたオープン ソース シングル サインオン プロジェクト分散シングル サインオン フレームワーク。一度ログインするだけで、相互に信頼できるすべてのアプリケーション システムにアクセスできます。「軽量、分散、クロスドメイン、Cookie+Token対応、Web+APP対応」などの特徴があります。

優れたオープン ソース シングル サインオン プロジェクト分散シングル サインオン フレームワーク。一度ログインするだけで、相互に信頼できるすべてのアプリケーション システムにアクセスできます。「軽量、分散、クロスドメイン、Cookie+Token対応、Web+APP対応」という特徴があります。

XXL-SSO は、分散シングル サインオン フレームワークです。一度ログインするだけで、相互に信頼できるすべてのアプリケーション システムにアクセスできます。「軽量、分散、クロスドメイン、Cookie+Token対応、Web+APP対応」という特徴があります。オープンソースになり、箱から出してすぐに使用できます。

XXL-JOB に精通している場合、これは非常に人気のある分散タスク スケジューリング プラットフォームです。しかし実際には、著者は XXL-SSO という非常に優れたオープン ソース プロジェクトも持っており、どちらも多くのスターを獲得しています。

1. sso への高速アクセス

1. xxl-ssoの特徴
簡潔:APIが直感的かつ簡潔で、すぐに始められる
軽量:環境への依存が少なく、導入やアクセスのコストが低い
シングルサインオン:必要なものはたった一つ一度ログインすると、相互に信頼できるすべてのアプリケーション システムにアクセスできます
分散型: SSO 認証センターのアプリケーションへのアクセス、分散展開のサポート
HA: サーバー側とクライアント側の両方がクラスター展開をサポートし、システムの可用性を向上させます クロス
ドメイン: クロスドメインをサポートしますSSO 認証センターへのアプリケーション アクセス
Cookie+Token サポート: Cookie に基づくサポートと Token の 2 つのアクセス方法に基づくサポート、および両方の提供 サンプル プロジェクト
Web+APP サポート: Web および APP アクセスのサポート
リアルタイム: システムのログインとログアウトのステータス、すべてのサーバーとクライアントは、リアルタイムの
CS 構造を共有します: サーバー「認証センター」とクライアント「保護されたアプリケーション」を含む CS 構造に基づきます
パスワードの記憶: パスワードが記憶されていない場合、ブラウザを閉じるとログイン ステータスが無効になります。パスワードを記憶すると、ログイン状態を自動的に延長することができます. カスタム延長時間に基づいて, 原則それは無期限に延長することができます. パスの除外: カスタムの
複数の除外パスをサポートし、Ant 式をサポートし、実行するパスを除外するために使用されます. SSO クライアントでフィルタリングする必要はありません

2. 環境
JDK: 1.7+
Redis: 4.0+

3. ソースアドレス
github: https://github.com/xuxueli/xxl-sso
gitee: https://gitee.com/xuxueli0323/xxl-sso

4. プロジェクト構造の説明

  • xxl-sso-server: 中央認証サービス、サポート クラスター
  • xxl-sso-core: クライアント側の依存関係
  • xxl-sso-samples: シングル サインオン クライアント アクセス サンプル プロジェクト
    • xxl-sso-web-sample-springboot: Cookie アクセス方式に基づく、ユーザー ブラウザ アクセス用、springboot バージョン
    • xxl-sso-token-sample-springboot: Token アクセス方式をベースに、アプリや Cookie が禁止されているなど、Cookie を使用できないシナリオで使用されることが多い

5. 構成図
ここに画像の説明を挿入
申請システム:sso-webシステム(ポート8081)、sso-webシステム(ポート8082)(ログインが必要なシステム)

SSO クライアント: ログイン、終了 (アプリケーション システムによって参照される独立した jar パッケージ)

SSOサーバー:login(ログインサービス)、login status(ログイン状態確認・ログイン情報照会サービス)、logout(ユーザーログアウトサービス)

データベース: ユーザー アカウント情報を保存します (通常は Mysql が使用され、現在のプロジェクトでは単純化のためにデータベースへのクエリは行われません)

キャッシュ: ユーザーのログイン情報を保存します (Redis を使用)

2. XXL-SSO フレームワークへのクイック アクセス
1. 認証センター (sso-server) の展開は、
構成ファイルを変更するだけで済みます. 構成ファイルの場所: application.properties

## 配置redis
xxl.sso.redis.address=redis://118.31.224.65:6379
##  登录态有效期窗口,默认24H,当登录态有效期窗口过半时,自动顺延一个周期
xxl.sso.redis.expire.minute=1440

2. Deploy the "Single Sign-On Client Access Sample Project"
here. ここでは、SSO にアクセスする必要があるシステムを指します. 現在のプロジェクトには、xxl-sso-web-sample-springboot と xxl-sso- の 2 つのサンプル プロジェクトがあります。 token-sample-springboot 、ここでは例として sso-web を取り上げます。

1)、maven の依存関係

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-sso-core</artifactId>
    <version>${最新稳定版}</version>
</dependency>

2) XxlSsoFilter を構成する

参照コード: com.xxl.sso.sample.config.XxlSsoConfig

@Bean
public FilterRegistrationBean xxlSsoFilterRegistration() {
    
    
    // xxl-sso, redis init
    JedisUtil.init(xxlSsoRedisAddress);
    // xxl-sso, filter init
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setName("XxlSsoWebFilter");
    registration.setOrder(1);
    registration.addUrlPatterns("/*");
    registration.setFilter(new XxlSsoWebFilter());
    registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
    registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);
    return registration;
}

application.propertiesの変更

## 中央认证服务地址
xxl.sso.server=http://ssoserver.com:8080/xxl-sso-server
## 退出接口
xxl.sso.logout.path=/logout
## 排除走sso的接口
xxl-sso.excluded.paths=/excludedUrl
## redis地址
xxl.sso.redis.address=redis://118.11.214.65:6379

3. 迅速な検証
1. ホスト ファイルの変更
ホスト ファイルの変更: ドメイン名で認証センターにアクセスし、クロスドメインおよびオンラインの実環境をシミュレートします。

127.0.0.1       ssoserver.com
127.0.0.1       webb.com
127.0.0.1       weba.com

2. 「xxl-sso-server」と「xxl-sso-web-sample-springboot」をそれぞれ実行するプロジェクト
を起動 シングルサインオンを確認するために、ここでは sso-web を 2 回起動する必要がありますが、1 回はポート 8081 と 1 回は 8082 ポートです。

## 1、SSO认证中心地址:
http://ssoserver.com:8080/xxl-sso-server
## 2、Client01应用地址:
http://weba.com:8081/xxl-sso-web-sample-springboot/
## 3、Client02应用地址:
http://webb.com:8082/xxl-sso-web-sample-springboot/

3.
SSO ログイン プロセスを確認する

通常、ログインプロセスは次のとおりです。

1.「Client01アプリケーションアドレス」にアクセスすると、「SSO認証センターアドレス」のログインインターフェースに自動でリダイレクトされます

ここに画像の説明を挿入

2. ログインに成功すると、自動的に「Client01 アプリケーションアドレス」にリダイレクトされ、ログイン状態に切り替わります
ここに画像の説明を挿入
3. このとき、ログインせずに「Client02 アプリケーションアドレス」にアクセスすると、自動的に「Client02 アプリケーションアドレス」に切り替わりますログイン状態
ここに画像の説明を挿入

明らかに、Client01 が正常にログインした後、Client02 は再度ログインしなくてもアクセスできます。

SSO ログアウト プロセス

通常の状況では、ログアウト プロセスは次のとおりです。

1.「Client01アプリケーションアドレス」に設定された「ログアウトパス」にアクセスすると、「SSO認証センターアドレス」に自動リダイレクトされ、ログイン状態から自動ログアウトされます
。アドレス」、また自動的にログアウト状態になります

4. コア コード分析
1. SSO クライアント (sso-core) インターセプターは
、主に sso インターセプターのプロセスに依存します。

 @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        // 获取当前请求接口
        String servletPath = req.getServletPath();
        // 1、是否是排除 不走sso的接口 如果是直接放行
        if (excludedPaths != null && excludedPaths.trim().length() > 0) {
    
    
            for (String excludedPath : excludedPaths.split(",")) {
    
    
                String uriPattern = excludedPath.trim();

                // 支持ANT表达式
                if (antPathMatcher.match(uriPattern, servletPath)) {
    
    
                    // excluded path, allow
                    chain.doFilter(request, response);
                    return;
                }
            }
        }
        // 2、是否是退出登录接口 
        if (logoutPath != null
                && logoutPath.trim().length() > 0
                && logoutPath.equals(servletPath)) {
    
    

            // 2.1删除当前请求客户端的cookie
            SsoWebLoginHelper.removeSessionIdByCookie(req, res);
            // 2.2重定向到sso认证服务的 退出接口
            String logoutPageUrl = ssoServer.concat(Conf.SSO_LOGOUT);
            res.sendRedirect(logoutPageUrl);
            return;
        }
        // 3、校验用户(是否存在,是否过期) 这个方法下面在展开
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(req, res);
        // 4、令牌校验失败
        if (xxlUser == null) {
    
    
            //获取当前请求地址
            String link = req.getRequestURL().toString();
            // 重定向到sso认证服务的 登录接口
            String loginPageUrl = ssoServer.concat(Conf.SSO_LOGIN)
                    + "?" + Conf.REDIRECT_URL + "=" + link;
            res.sendRedirect(loginPageUrl);
            return;
        }
        // ser sso user
        request.setAttribute(Conf.SSO_USER, xxlUser);
        // 已经登录 放行
        chain.doFilter(request, response);
        return;
    }

上記の loginCheck メソッドを見てください。

   /**
     * 令牌校验
     *
     * @return 用户信息
     */
    public static XxlSsoUser loginCheck(HttpServletRequest request, HttpServletResponse response){
    
    

        //去cookie去获取xxl_sso_sessionid 其实就是之前原理篇说的token,只是名称叫法不同
        String cookieSessionId = CookieUtil.getValue(request, Conf.SSO_SESSIONID);
        
        // 这里去redis中获取用户信息 有可能获取不到。这个方法就不粘贴了 这里有三种情况
        //1、cookieSessionId为空 那么直接返回null
        //2、cookieSessionId不为空,但在redis获取不到用户信息,因为存在其它系统退出后 redis删除了
        //3、redis获取到了用户信息,但超过有效期了 依旧返回null
        XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(cookieSessionId);
        if (xxlUser != null) {
    
    
            return xxlUser;
        }
        // 如果获取不到 所以已经在其它系统退出登录了 那删除cookie中的xxl_sso_sessionid
        SsoWebLoginHelper.removeSessionIdByCookie(request, response);
        //如果是 sso登录成功后 回调过来的 这个时候在这里是可以获取到xxl_sso_sessionid的
        String paramSessionId = request.getParameter(Conf.SSO_SESSIONID);
        xxlUser = SsoTokenLoginHelper.loginCheck(paramSessionId);
        if (xxlUser != null) {
    
    
            CookieUtil.set(response, Conf.SSO_SESSIONID, paramSessionId, false);    /
            return xxlUser;
        }
        return null;
    }

2. 認証サーバー (sso-server) ログインインターフェース

  /**
     * sso认证中心 登录接口
     */
    @RequestMapping(Conf.SSO_LOGIN)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {
    
    

        // 同样的 该判断sso上有没有全局会话 
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);
        //如果 其它系统登录成功过 这个就不回为null 直接再带上xxl_sso_sessionid=xxx 重定向到之前接口
        //也不用在登录了
        if (xxlUser != null) {
    
    
            // success redirect
            String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
            if (redirectUrl!=null && redirectUrl.trim().length()>0) {
    
    

                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;;
                return "redirect:" + redirectUrlFinal;
            } else {
    
    
                return "redirect:/";
            }
        }
        //只有全局会话不存在 才会跳转登录页面 
        model.addAttribute("errorMsg", request.getParameter("errorMsg"));
        model.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "login";
    }

3. 認証サーバー (sso-server) 出口インターフェース

 @RequestMapping(Conf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
    
    
        // 退出操作
        SsoWebLoginHelper.logout(request, response);
        // 跳转到登录页
        redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "redirect:/login";
    }

logout メソッドの機能を見てみましょう

 public static void logout(HttpServletRequest request,
                              HttpServletResponse response) {
    
    

        String cookieSessionId = CookieUtil.getValue(request, Conf.SSO_SESSIONID);
        if (cookieSessionId==null) {
    
    
            return;
        }
        //1、删除全局缓存 redis中 清除cookieSessionId,这样其它系统在令牌校验的时候 会失败。即一处退出,处处退出。
        String storeKey = SsoSessionIdHelper.parseStoreKey(cookieSessionId);
        if (storeKey != null) {
    
    
            SsoLoginStore.remove(storeKey);
        }
        //2、清除全局会话 
        CookieUtil.remove(request, response, Conf.SSO_SESSIONID);
    }

コアコード全体のロジックはここにあり、実際、前の記事の理論と組み合わせると、理解するのはまったく複雑ではありません。

おすすめ

転載: blog.csdn.net/u014374009/article/details/129193246