统一用户登陆系统
?
單點(diǎn)登陸的定義:
???????? ?
簡稱為 SSO,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。SSO的定義是在多個(gè)應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)。
?????
技術(shù)實(shí)現(xiàn)機(jī)制:
?? ??當(dāng)用戶第一次訪問應(yīng)用系統(tǒng)1的時(shí)候,因?yàn)檫€沒有登錄,會(huì)被引導(dǎo)到認(rèn)證系統(tǒng)中進(jìn)行登錄;根據(jù)用戶提供的登錄信息,認(rèn)證系統(tǒng)進(jìn)行身份效驗(yàn),如果通過效驗(yàn),應(yīng)該返回給用戶一個(gè)認(rèn)證的憑據(jù)--ticket;用戶再訪問別的應(yīng)用的時(shí)候,就會(huì)將這個(gè)ticket帶上,作為自己認(rèn)證的憑據(jù),應(yīng)用系統(tǒng)接受到請(qǐng)求之后會(huì)把ticket送到認(rèn)證系統(tǒng)進(jìn)行效驗(yàn),檢查ticket的合法性。如果通過效驗(yàn),用戶就可以在不用再次登錄的情況下訪問應(yīng)用系統(tǒng)2和應(yīng)用系統(tǒng)3了。
?
開源的jasig單點(diǎn)登入系統(tǒng)包括如下:
????? cas-server-3.4.10:統(tǒng)一用戶登入的驗(yàn)證系統(tǒng)
????? cas-client-3.2.1:?用戶客戶端引入的文件
?
以java系統(tǒng)為例:
?
統(tǒng)一用戶系統(tǒng)的集成步驟:
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
?
??? <!-- 用于單點(diǎn)退出,該過濾器用于實(shí)現(xiàn)單點(diǎn)登出功能,可選配置-->
<listener>
?????? <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
?
<!-- 該過濾器用于實(shí)現(xiàn)單點(diǎn)登出功能,可選配置。 -->
<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>
?
<!-- 該過濾器負(fù)責(zé)用戶的認(rèn)證工作,必須啟用它 -->
<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是服務(wù)端的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>
?
<!-- 該過濾器負(fù)責(zé)對(duì)Ticket的校驗(yàn)工作,必須啟用它 -->
<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>
?
<!--
?????? 該過濾器負(fù)責(zé)實(shí)現(xiàn)HttpServletRequest請(qǐng)求的包裹,
?????? 比如允許開發(fā)者通過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>
?
<!--
?????? 該過濾器使得開發(fā)者可以通過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>
?
<!-- 自動(dòng)根據(jù)單點(diǎn)登錄的結(jié)果設(shè)置本系統(tǒng)的用戶信息 -->
<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>
<!-- ======================== 單點(diǎn)登錄結(jié)束 ======================== -->
??? ????
?
?
?
?
3) 添加AutoSetUserAdapterFilter這個(gè)類,來自動(dòng)根據(jù)CAS信息設(shè)置Session的用戶信息,
主要是通過CAS的_const_cas_assertion_獲取從CAS服務(wù)器登陸的用戶名,然后再根據(jù)系統(tǒng)內(nèi)部的用戶工具(UserUtil.java)來判斷是否已經(jīng)登錄過,如果沒有登錄根據(jù)登錄名從數(shù)據(jù)庫查詢用戶信息,最后使用設(shè)置把用戶信息設(shè)置到當(dāng)前session中。
這樣就把用戶信息保存到了Sessino中,我們就可以通過UserUtil工具來獲取當(dāng)前登錄的用戶了
?????
?
public class AutoSetUserAdapterFilter implements Filter {
???????
??????? /**
???????? * Defaultconstructor.
???????? */
??????? publicAutoSetUserAdapterFilter() {
??????? }
?
??????? /**
???????? * @seeFilter#destroy()
???????? */
??????? public voiddestroy() {
??????? }
?
??????? /**
???????? * 過濾邏輯:首先判斷單點(diǎn)登錄的賬戶是否已經(jīng)存在本系統(tǒng)中,
???????? * 如果不存在使用用戶查詢接口查詢出用戶對(duì)象并設(shè)置在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標(biāo)志
??????????????? 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());
???????????????????????
???????????????????????// 第一次登錄系統(tǒng)
???????????????????????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 {
??????? }
}
?
相關(guān)知識(shí):http://hhw3.blog.163.com/blog/static/2690966201411265579770/
總結(jié)
- 上一篇: 第八十一期:Java性能优化:35个小细
- 下一篇: 设计模式 日志系统设计_模式:我们设计系