一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java單點登錄(SSO)的實現

java單點登錄(SSO)的實現

2021-10-09 01:46瘋狂打碼 Java教程

SSO是指在多個應用系統中個,用戶只需要登陸一次就可以訪問所有相互信任的應用系統,本文主要介紹了java單點登錄的實現,具有一定的參考價值,感興趣的可以了解一下

單點登錄(SSO):SSO是指在多個應用系統中個,用戶只需要登陸一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登錄映射到其他應用中用于同一用戶的登陸的機制。

SSO的實現過程:

java單點登錄(SSO)的實現

通過上述圖形,我們可以看到SSO的大體實現步驟主要分為兩大步:存儲登錄信息,查驗登錄信息。

對于SSO,我們也可以將之分為兩大不同的類型:同域SSO和跨域SSO;其中同域SSO又可以分為完全同域SSO和同父域SSO。

一、完全同域SSO:指的是域名完全相同的多個應用系統中實現單點登錄。

其實現步驟主要分為:前期準備工作,編寫統一登錄接口,編寫登錄校驗接口,編寫驗證頁面,實現SSO;

編寫統一登錄接口:
登錄頁面的編寫主要是錄入用戶的登錄信息,包括用戶名,密碼,以及登錄頁面的地址。因為存在多個應用系統,所以用戶在統一登錄頁面登陸成功后,系統需要知道用戶想要訪問的是哪個系統頁面,這個時候就需要記錄用戶第一次訪問的地址,等到用戶登錄成功后,就可直接跳轉該頁面。

?
1
2
3
4
5
6
7
8
9
10
11
12
<body>
    <center>
        <h1>請登錄</h1>
        <form action="/sso/doLogin.action" method="POST">
            <span>用戶名:</span><input type="text" name="username" />
            <span>密碼:</span><input type="text" name="password" />
            //暫存需要登錄頁面的url地址
            <input type="hidden" name="gotoUrl" value="${gotoUrl}" />
            <input type="submit" />
        </form>
    </center>
</body>

登錄方法的編寫:需要新建cookie,將用戶的信息存進cookie中,并指定cookie的路徑,因為是完全同域,所以cookie的地址可以簡寫為(“/”)。這里必須要設置cookie的路徑,如果不設置,那么cookie的路徑將并不一定在當前域名的頂層,它有可能就在當前的這個路徑下才可見,這樣會導致在當前域的其他路徑下找不到這個cookie,解決辦法就是把cookie設置到當前域的最頂層域里面,這樣當前域下的所有應用就會都可見。

?
1
2
3
4
5
6
7
8
9
public String doLogin(){
        //新建Cookie
        Cookie cookie = new Cookie("ssocookie","sso");
        //設置Cookie路徑
        cookie.setPath("/");
        HttpServletResponse response = ServletActionContext.getResponse();
        response.addCookie(cookie);
        return "success";
 }

登錄校驗接口的編寫:通常SSO登錄接口校驗都會放在登錄攔截器中,當用戶想要訪問某個系統時,登錄攔截器將直接重定向到統一登錄頁面,用戶填寫完登錄信息后,就會進行登錄校驗。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
//cookie校驗(放在攔截器中進行校驗)
    public static boolean checkCookie(HttpServletRequst request){
        Cookie[] cookies=request.getCookies();
        if(cookies!=null){
            for(Cookies cookie:cookies){
                if(cookie.getName().equals("ssocookie")
                        &&cookie.getValue().equals("sso")){
                    return true;
                }
            }
        }
        return false;
  }

編寫測試主頁

?
1
2
3
4
5
6
7
8
9
10
public String main(){
        HttpServletRequst request = ServletActionContext.getRequst();
        if(SSOCheck.checkCookie(request)){
            //登陸成功,記錄用戶登錄信息......
            return "success";
        }
        //登錄失敗,暫存需要訪問的地址,登錄成功后,直接訪問該地址
        gotoUrl="/demo1/main.action";
        return "login";
 }

最后還有struts2的配置文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<struts>
    <package name="sso" namespace="/sso" extends="struts-default">
        <action name="doLogin" class="com.xm.controllerAction.SSOAction" method="doLogin">
       <!-- 用戶登錄成功后,需要進行重定向,重新跳轉到用戶最初訪問的路徑 -->
            <result name="success" type="redirect">${gotoUrl}</result>
        </action>
    </package>
    
    <package name="demo1" namespace="/demo1" extends="struts-default">
        <action name="main" class="com.xm.controllerAction.Demo1Action" method="main">
            <result name="success">/success1.jsp</result>
            <result name="login">/login.jsp</result>
        </action>
    </package>
    <package name="demo2" namespace="/demo2" extends="struts-default">
        <action name="main" class="com.xm.controllerAction.Demo2Action" method="main">
            <result name="success">/success2.jsp</result>
            <result name="login">/login.jsp</result>
        </action>
    </package>
</struts>

二、同父域SSO:指的是父域名相同的應用系統上實現SSO。

其實現步驟與上述完全同域SSO相同。

其中檢驗域名:http://check.x.com

測試頁面域名:http://demo1.x.com和http://demo2.x.com

編寫統一登錄接口:
代碼實現與完全同域名SSO基本一致,不過在設置提交路徑時,因為二級域名不同,所以不能寫成相對路徑,需要寫成絕對路徑地址。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
    <center>
        <h1>請登錄</h1>
     //表單提交地址需寫成絕對路徑,不能寫相對路徑
        <form action="http://check.x.com/sso/doLogin.action" method="POST">
            <span>用戶名:</span><input type="text" name="username" />
            <span>密碼:</span><input type="text" name="password" />
            //暫存需要登錄頁面的url地址
            <input type="hidden" name="gotoUrl" value="${gotoUrl}" />
            <input type="submit" />
        </form>
    </center>
</body>

登錄方法:在設置cookie路徑的時候有所變化,同上,為了使得當前兩個同父域的應用系統都可見這個cookie,那么我們需要將這個cookie設置到父域下面,而不應該設置到本域下面,這樣才可以實現域不同,但是父域相同的應用都可以看到的這個cookie。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String doLogin(){
   boolean ok = SSOCheck.checkLogin(userName,passWord);
   if(ok){
        //新建Cookie
        Cookie cookie = new Cookie("ssocookie","sso");
        //設置Cookie的父域
        cookie.setDomain(".x.com");
        //設置Cookie路徑
        cookie.setPath("/");
        HttpServletResponse response = ServletActionContext.getResponse();
        response.addCookie(cookie);
        return "success";
   }
}

登錄校驗接口:因為有著不同的域,所以我們應該將登錄所獲得cookie傳到專門的校驗域下的校驗方法中進行校驗,否則我們需要在各自不同的登錄頁面實現校驗,這樣顯得代碼十分的冗余。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    private String cookieName;
    private String cookieValue;
    public String getCookieName() {
      return cookieName;
    }
    public void setCookieName(String cookieName) {
      this.cookieName = cookieName;
    }
    public String getCookieValue() {
      return cookieValue;
    }
    public void setCookieValue(String cookieValue) {
      this.cookieValue = cookieValue;
    }
 
 
   //二級域名向二級域名發送請求
    public void checkCookie() throws IOException{
        boolean ok=SSOCheck.checkCookie(cookieName,cookieValue);
        String result="0";
        if(ok){
            result="1";
        }
        HttpServletResponse response = ServletActionContext.getResponse();
        response.getWriter().print(result);
        response.getWriter().close();
    }
 
 
public static boolean checkCookie(String cookieName,String cookieValue){
        if(cookieName.equals("ssocookie")&&cookieValue.equals("sso")){
            return true;
        }
        return false;
    }

編寫測試主頁

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public String main(){
        HttpServletRequst request = ServletActionContext.getRequst();
     //獲取cookie
        Cookie[] cookies=request.getCookies();
        if(cookies!=null){
            for(Cookie cookie:cookies){
                if(cookie.getName().equals("ssocookie")){
            //向檢驗服務器中發送cookieName和cookieValue
                    String result = Demo1Tool.doGet("http://check.x.com/so/checkCookie.action",
                            cookie.getName(),cookie.getValue());
                    if(result.equals("1")){
                        return "success";
                    }
                }
            }
        }
        //暫存需要訪問的地址,登錄成功后,直接訪問該地址
        gotoUrl="http://demo1.x.com/demo1/main.action";
        return "login";
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static String doGet(String url,String cookieName,String cookieValue){
        //定義返回值
        StringBuffer sb = new StringBuffer();
        HttpURLConnection httpURLConnection = null;
        try{
            //校驗方法所在的地址
            URL urls = new URL(url+
                    "?cookieName="+cookieName+"&cookieValue="+cookieValue);
            //打開連接
            httpURLConnection = (HttpURLConnection) urls.openConnection();
            //設置打開連接的方法
            httpURLConnection.setRequestMethod("GET");
            //開始連接
            httpURLConnection.connect();
            InputStream in = httpURLConnection.getInputStream();
            InputStreamReader isr = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(isr);
            String temp = null;
            while((temp = br.readLine())!=null){
                sb.append(temp);
            }
            br.close();
            isr.close();
            in.close();
        } catch(IOException e){
            e.printStackTrace();
        } finally{
            if(httpURLConnection!=null){
                httpURLConnection.disconnect();
            }
        }
        return sb.toString();
}

struts配置文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<struts>
    <package name="sso" namespace="/sso" extends="struts-default">
        <action name="doLogin" class="com.xm.controllerAction.SSOAction" method="doLogin">
            <result name="success" type="redirect">${gotoUrl}</result>
        </action>
        <action name="checkCookie" class="check.x.com.SSOAction" method="checkCookie">
        </action>
    </package>
    <package name="demo1" namespace="/demo1" extends="struts-default">
        <action name="main" class="demo1.x.com.Demo1Action" method="main">
            <result name="success">/success1.jsp</result>
            <result name="login">/login.jsp</result>
        </action>
    </package>
    <package name="demo2" namespace="/demo2" extends="struts-default">
        <action name="main" class="demo2.x.com.Demo2Action" method="main">
            <result name="success">/success2.jsp</result>
            <result name="login">/login.jsp</result>
        </action>
    </package>
</struts>

三、跨域SSO:在域名完全不同的應用程序上實現SSO。

其實現步驟與完全同域SSO相同。

其中檢驗域名:http://www.x.com

測試頁面域名:http://www.a.com和http://www.b.com

編寫統一登錄接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
    <center>
        <h1>請登錄</h1>
        //這里需要向當前所在的域提交申請,因為如果向校驗域提交申請,那么在本域中將無法看到cookie
        <form action="/${path}/doLogin.action" method="POST">
            <span>用戶名:</span><input type="text" name="username" />
            <span>密碼:</span><input type="text" name="password" />
            //暫存需要登錄頁面的url地址
            <input type="hidden" name="gotoUrl" value="${gotoUrl}" />
            <input type="submit" />
        </form>
    </center>
</body>

登錄方法:

?
1
2
3
4
5
6
7
8
9
10
public String doLogin(){
        Map<String,String> map = new HashMap<String,String>();
        map.put("userName", userName);
        map.put("password", passWord);
        String result = Demo1Tool.doGet("http://www.x.com/sso/doLogin.action",map);
        if(result.equals("1")){
            return "success";
        }
        return "login";
}
?
1
2
3
4
5
6
7
8
9
10
public void doLogin() throw IOException{
        boolean ok=SSOCheck.checkCookie(cookieName,cookieValue);
        String result = "0";
        if(ok){
            result = "1";
        }
        HttpServletResponse response = ServletActionContext.getResponse();
        response.getWriter().print(result);
        response.getWriter().close();
}

登錄校驗接口;和同父域SSO的登錄校驗基本一致,沒有什么變化。

?
1
2
3
4
5
6
7
8
9
10
public void checkCookie() throws IOException{
        boolean ok=SSOCheck.checkCookie(cookieName,cookieValue);
        String result="0";
        if(ok){
            result="1";
        }
        HttpServletResponse response = ServletActionContext.getResponse();
        response.getWriter().print(result);
        response.getWriter().close();
}

編寫測試主頁

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public String main(){
        HttpServletRequst request = ServletActionContext.getRequst();
        Cookie[] cookies=request.getCookies();
        if(cookies!=null){
            for(Cookie cookie:cookies){
                if(cookie.getName().equals("ssocookie")){
                    Map<String,String> map = new HashMap<String,String>();
                    map.put("userName", cookie.getName());
                    map.put("password", cookie.getValue());
                    String result = Demo1Tool.doGet("http://www.x.com/so/checkCookie.action",
                            cookie.getName(),cookie.getValue());
                    if(result.equals("1")){
                        return "success";
                    }
                }
            }
        }
        //暫存需要訪問的地址,登錄成功后,直接訪問該地址
        path = "demo1";
        gotoUrl="http://www.a.com/demo1/main.action";
        return "login";
    }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static String doGet(String url,Map<String,String> map){
        //定義返回值
        StringBuffer sb = new StringBuffer();
        HttpURLConnection httpURLConnection = null;
        try{
            StringBuffer t_s = new StringBuffer(url).append("?");
            for(Map.Entry<String, String> entry:map.entrySet()){
                t_s.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                
            }
            url = t_s.substring(0,t_s.length()-1);
            //校驗方法所在的地址
            URL urls = new URL(url);
            //打開連接
            httpURLConnection = (HttpURLConnection) urls.openConnection();
            //設置打開連接的方法
            httpURLConnection.setRequestMethod("GET");
            //開始連接
            httpURLConnection.connect();
            InputStream in = httpURLConnection.getInputStream();
            InputStreamReader isr = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(isr);
            String temp = null;
            while((temp = br.readLine())!=null){
                sb.append(temp);
            }
            br.close();
            isr.close();
            in.close();
        } catch(IOException e){
            e.printStackTrace();
        } finally{
            if(httpURLConnection!=null){
                httpURLConnection.disconnect();
            }
        }
        return sb.toString();
    }

至此,準備工作做完,接下來是跨域SSO實現中最重要的部分,也就是cookie的設置,在之前完全同域和同父域的情況下,為了實現SSO,我們在進行doLogin時就設置了cookie,因為域名相同,所以十分簡單,但是在跨域SSO中,因為不同域之間的cookie是不可見的,所以我們不可能只設置一個cookie,然后令所有的域名下的應用程序皆可見,所以我們應該在每個域下面都有著為本域設置cookie的方法,而不應該直接將設置cookie交給校驗域。

?
1
2
3
4
5
6
7
//為本域設置cookie的方法
    public void addCookie(){
        Cookie cookie = new Cookie("ssocookie","sso");
        cookie.setPath("/");
        HttpServletResponse response = ServletActionContext.getResponse();
        response.addCookie(cookie);
    }

還需要在配置文件中進行配置:

?
1
<action name="addCookie" class="www.a.com.Demo1Action" method="addCookie"></action>

寫完好方法,則需要進行調用,因此我們需要找一個可以讓二者進行交會的地方,在這里我選擇了登錄成功的瞬間,通過隱藏的Iframe讓二者進行交會。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public String doLogin(){
        Map<String,String> map = new HashMap<String,String>();
        map.put("userName", userName);
        map.put("password", passWord);
        String result = Demo1Tool.doGet("http://www.x.com/sso/doLogin.action",map);
        if(result.equals("1")){
            return "success";
        }
        List hidderUrl = new ArrayList<String>();
        hidderUrl.add("http://www.a.com/demo1/addCookie.action");
        hidderUrl.add("http://www.b.com/demo2/addCookie.action");
        return "login";
    }
?
1
2
3
<c:forEach var="url" item="${hiddenUrl}">
    <iframe src="${url}" width="0px" heigth="0px" style="display:none"></iframe>
</c:forEach>

到此這篇關于java單點登錄(SSO)的實現的文章就介紹到這了,更多相關java單點登錄內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/libinhyq/p/9561582.html

延伸 · 閱讀

精彩推薦
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
主站蜘蛛池模板: 国产高清亚洲 | 猫咪社区在线播放 | 欧美va免费大片 | 好大好爽好涨太深了小喜 | 天美传媒在线视频 | 国产精品亚洲综合第一区 | 国产区小视频 | 日韩欧美国产一区二区三区 | 成人福利影院 | 欧美美女一级片 | 出轨娇妻的呻吟1—9 | 免费视频完整版在线观看网站 | 羞羞视频动漫 | 精品国产日韩亚洲一区在线 | 精品久久久久久久高清 | 欧美日韩精品在线观看 | 亚洲社区在线观看 | 国产精品一级香蕉一区 | 欧美一区二区三区免费观看视频 | 国产亚洲精品美女 | 精品推荐国产麻豆剧传媒 | 69短视频| 双性总裁(h) | 15一16japanese破| 国产免费久久精品44 | 激情乱文 | 国产精品吹潮香蕉在线观看 | 亚洲福利视频一区 | 幻女free性zoz0交 | 亚洲一区二区三区福利在线 | 女人被爽到呻吟娇喘的视频动态图 | 91免费播放| 国产精品51麻豆cm传媒 | 久青草国产观看在线视频 | 91制片| 34看网片午夜理 | chinese特色video| 亚洲AV无码国产精品色在线看 | 欧美精品一线二线大片 | 男人和女人全黄一级毛片 | 猫扑俩性 |