统一用户登陆系统
?
單點登陸的定義:
???????? ?
簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。
?????
技術實現機制:
?? ??當用戶第一次訪問應用系統1的時候,因為還沒有登錄,會被引導到認證系統中進行登錄;根據用戶提供的登錄信息,認證系統進行身份效驗,如果通過效驗,應該返回給用戶一個認證的憑據--ticket;用戶再訪問別的應用的時候,就會將這個ticket帶上,作為自己認證的憑據,應用系統接受到請求之后會把ticket送到認證系統進行效驗,檢查ticket的合法性。如果通過效驗,用戶就可以在不用再次登錄的情況下訪問應用系統2和應用系統3了。
?
開源的jasig單點登入系統包括如下:
????? cas-server-3.4.10:統一用戶登入的驗證系統
????? cas-client-3.2.1:?用戶客戶端引入的文件
?
以java系統為例:
?
統一用戶系統的集成步驟:
http://www.ja-sig.org/downloads/cas-clients/
?
1)下載cas客戶端jar包
cas-client-core-3.2.1.jar
把此jar包放到WEB-INF\lib目錄下
?
2)修改web.xml添加cas過濾器filter
?
??? <!-- 用于單點退出,該過濾器用于實現單點登出功能,可選配置-->
<listener>
?????? <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
?
<!-- 該過濾器用于實現單點登出功能,可選配置。 -->
<filter>
?????? <filter-name>CASSingle Sign Out Filter</filter-name>
?????? <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
?????? <filter-name>CASSingle Sign Out Filter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
?
<!-- 該過濾器負責用戶的認證工作,必須啟用它 -->
<filter>
?????? <filter-name>CASFilter</filter-name>
?????? <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
?????? <init-param>
????????????? <param-name>casServerLoginUrl</param-name>
????????????? <param-value>https://sso.haier.com:8443/cas/login</param-value>
????????????? <!--這里的server是服務端的IP-->
?????? </init-param>
?????? <init-param>
????????????? <param-name>serverName</param-name>
????????????? <param-value>http://www.haiertest.com:58080</param-value>
?????? </init-param>
</filter>
<filter-mapping>
?????? <filter-name>CASFilter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
?
<!-- 該過濾器負責對Ticket的校驗工作,必須啟用它 -->
<filter>
?????? <filter-name>CASValidation Filter</filter-name>
?????? <filter-class>
????????????? org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
?????? <init-param>
????????????? <param-name>casServerUrlPrefix</param-name>
????????????? <param-value>https://sso.haier.com:8443/cas</param-value>
?????? </init-param>
?????? <init-param>
????????????? <param-name>serverName</param-name>
????????????? <param-value>http://www.haiertest.com:58080</param-value>
?????? </init-param>
</filter>
<filter-mapping>
?????? <filter-name>CASValidation Filter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
?
<!--
?????? 該過濾器負責實現HttpServletRequest請求的包裹,
?????? 比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登錄用戶的登錄名,可選配置。
-->
<filter>
?????? <filter-name>CASHttpServletRequest Wrapper Filter</filter-name>
?????? <filter-class>
????????????? org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
?????? <filter-name>CASHttpServletRequest Wrapper Filter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
?
<!--
?????? 該過濾器使得開發者可以通過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登錄名。
?????? 比如AssertionHolder.getAssertion().getPrincipal().getName()。
-->
<filter>
?????? <filter-name>CASAssertion Thread Local Filter</filter-name>
?????? <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
?????? <filter-name>CASAssertion Thread Local Filter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
?
<!-- 自動根據單點登錄的結果設置本系統的用戶信息 -->
<filter>
?????? <display-name>AutoSetUserAdapterFilter</display-name>
?????? <filter-name>AutoSetUserAdapterFilter</filter-name>
?????? <filter-class>com.haier.demo.filter.AutoSetUserAdapterFilter</filter-class>
</filter>
<filter-mapping>
?????? <filter-name>AutoSetUserAdapterFilter</filter-name>
?????? <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ======================== 單點登錄結束 ======================== -->
??? ????
?
?
?
?
3) 添加AutoSetUserAdapterFilter這個類,來自動根據CAS信息設置Session的用戶信息,
主要是通過CAS的_const_cas_assertion_獲取從CAS服務器登陸的用戶名,然后再根據系統內部的用戶工具(UserUtil.java)來判斷是否已經登錄過,如果沒有登錄根據登錄名從數據庫查詢用戶信息,最后使用設置把用戶信息設置到當前session中。
這樣就把用戶信息保存到了Sessino中,我們就可以通過UserUtil工具來獲取當前登錄的用戶了
?????
?
public class AutoSetUserAdapterFilter implements Filter {
???????
??????? /**
???????? * Defaultconstructor.
???????? */
??????? publicAutoSetUserAdapterFilter() {
??????? }
?
??????? /**
???????? * @seeFilter#destroy()
???????? */
??????? public voiddestroy() {
??????? }
?
??????? /**
???????? * 過濾邏輯:首先判斷單點登錄的賬戶是否已經存在本系統中,
???????? * 如果不存在使用用戶查詢接口查詢出用戶對象并設置在Session中
???????? * @seeFilter#doFilter(ServletRequest, ServletResponse, FilterChain)
???????? */
??????? public voiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException,
???????????????????????ServletException {
???? ???????????HttpServletRequest httpRequest =(HttpServletRequest) request;
???????????????
??????????????? //_const_cas_assertion_是CAS中存放登錄用戶名的session標志
??????????????? Objectobject =httpRequest.getSession().getAttribute("_const_cas_assertion_");
???????????????
??????????????? if(object != null) {
???????????????????????Assertion assertion = (Assertion) object;
???????????????????????String loginName = assertion.getPrincipal().getName();
???????????????????????User user = UserUtil.getCurrentUser(httpRequest.getSession());
???????????????????????
???????????????????????// 第一次登錄系統
???????????????????????if (user == null) {
???????????????????????????????WebApplicationContext wct =WebApplicationContextUtils.getWebApplicationContext(httpRequest
???????????????????????????????????????????????.getSession().getServletContext());
??????????????????????????????? UserManageruserManager = (UserManager) wct.getBean("userManager");
??????????????????????????????? user =userManager.findUserByLoginName(loginName);
??????????????????????????????? // 保存用戶信息到Session
???????????????????????????????UserUtil.saveUserToSession(httpRequest.getSession(), user);
???????????????????????}
???????????????????????
??????????????? }
???????????????chain.doFilter(request, response);
??????? }
?
??????? /**
???????? * @seeFilter#init(FilterConfig)
???????? */
??????? public voidinit(FilterConfig fConfig) throws ServletException {
??????? }
}
?
相關知識:http://hhw3.blog.163.com/blog/static/2690966201411265579770/
總結
- 上一篇: 第八十一期:Java性能优化:35个小细
- 下一篇: 什么是设计模式_什么是设计?