- 浏览: 576678 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
a1641693970:
还不错,学习了
BeanUtils使用总结(二)LazyDynaBean -
zjfshowtime:
很好的办法,学习了。
ORA-28001: the password has expired -
ya654277yo:
哦,多谢分享
Apache整合Tomcat后get方式提交中文乱码问题解决 -
foolkeeper:
nice !!
jvm内存参数设定 -
tracy821:
谢谢了,找了好久才找到
关于Spring 声明式事务处理时,throws exception不回滚的问题
3.2 WEB-SSO代码讲解
3.2.1身份认证服务代码解析
Web-SSO的源代码可以从网站地址http://gceclub.sun.com.cn/wangyu/web-sso/websso_src.zip下载。身份认证服务是一个标准的web应用,包括一个名为SSOAuth的Servlet,一个login.jsp文件和一个failed.html。身份认证的所有服务几乎都由SSOAuth的Servlet来实现了;login.jsp用来显示登录的页面(如果发现用户还没有登录过);failed.html是用来显示登录失败的信息(如果用户的用户名和密码与信息数据库中的不一样)。
SSOAuth的代码如下面的列表显示,结构非常简单,先看看这个Servlet的主体部分:
package DesktopSSO; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.concurrent.*; import javax.servlet.*; import javax.servlet.http.*; public class SSOAuth extends HttpServlet { static private ConcurrentMap accounts; static private ConcurrentMap SSOIDs; String cookiename="WangYuDesktopSSOID"; String domainname; public void init(ServletConfig config) throws ServletException { super.init(config); domainname= config.getInitParameter("domainname"); cookiename = config.getInitParameter("cookiename"); SSOIDs = new ConcurrentHashMap(); accounts=new ConcurrentHashMap(); accounts.put("wangyu", "wangyu"); accounts.put("paul", "paul"); accounts.put("carol", "carol"); } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String action = request.getParameter("action"); String result="failed"; if (action==null) { handlerFromLogin(request,response); } else if (action.equals("authcookie")){ String myCookie = request.getParameter("cookiename"); if (myCookie != null) result = authCookie(myCookie); out.print(result); out.close(); } else if (action.equals("authuser")) { result=authNameAndPasswd(request,response); out.print(result); out.close(); } else if (action.equals("logout")) { String myCookie = request.getParameter("cookiename"); logout(myCookie); out.close(); } } ..... }
从代码很容易看出,SSOAuth就是一个简单的Servlet。其中有两个静态成员变量:accounts和SSOIDs,这两个成员变量都使用了JDK1.5中线程安全的MAP类: ConcurrentMap,所以这个样例一定要JDK1.5才能运行。Accounts用来存放用户的用户名和密码,在init()的方法中可以看到我给系统添加了三个合法的用户。在实际应用中,accounts应该是去数据库中或LDAP中获得,为了简单起见,在本样例中我使用了ConcurrentMap在内存中用程序创建了三个用户。而SSOIDs保存了在用户成功的登录后所产生的cookie和用户名的对应关系。它的功能显而易见:当用户成功登录以后,再次访问别的系统,为了鉴别这个用户请求所带的cookie的有效性,需要到SSOIDs中检查这样的映射关系是否存在。
在主要的请求处理方法processRequest()中,可以很清楚的看到SSOAuth的所有功能
- 如果用户还没有登录过,是第一次登录本系统,会被跳转到login.jsp页面(在后面会解释如何跳转)。用户在提供了用户名和密码以后,就会用handlerFromLogin()这个方法来验证。
- 如果用户已经登录过本系统,再访问别的应用的时候,是不需要再次登录的。因为浏览器会将第一次登录时产生的cookie和请求一起发送。效验cookie的有效性是SSOAuth的主要功能之一。
- SSOAuth还能直接效验非login.jsp页面过来的用户名和密码的效验请求。这个功能是用于非web应用的SSO,这在后面的桌面SSO中会用到。
- SSOAuth还提供logout服务。
下面看看几个主要的功能函数:
private void handlerFromLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String pass = (String)accounts.get(username); if ((pass==null)||(!pass.equals(password))) getServletContext().getRequestDispatcher("/failed.html").forward(request, response); else { String gotoURL = request.getParameter("goto"); String newID = createUID(); SSOIDs.put(newID, username); Cookie wangyu = new Cookie(cookiename, newID); wangyu.setDomain(domainname); wangyu.setMaxAge(60000); wangyu.setValue(newID); wangyu.setPath("/"); response.addCookie(wangyu); System.out.println("login success, goto back url:" + gotoURL); if (gotoURL != null) { PrintWriter out = response.getWriter(); response.sendRedirect(gotoURL); out.close(); } } }
handlerFromLogin()这个方法是用来处理来自login.jsp的登录请求。它的逻辑很简单:将用户输入的用户名和密码与预先设定好的用户集合(存放在accounts中)相比较,如果用户名或密码不匹配的话,则返回登录失败的页面(failed.html),如果登录成功的话,需要为用户当前的session创建一个新的ID,并将这个ID和用户名的映射关系存放到SSOIDs中,最后还要将这个ID设置为浏览器能够保存的cookie值。
登录成功后,浏览器会到哪个页面呢?那我们回顾一下我们是如何使用身份认证服务的。一般来说我们不会直接访问身份服务的任何URL,包括login.jsp。身份服务是用来保护其他应用服务的,用户一般在访问一个受SSOAuth保护的Web应用的某个URL时,当前这个应用会发现当前的用户还没有登录,便强制将也页面转向SSOAuth的login.jsp,让用户登录。如果登录成功后,应该自动的将用户的浏览器指向用户最初想访问的那个URL。在handlerFromLogin()这个方法中,我们通过接收“goto”这个参数来保存用户最初访问的URL,成功后便重新定向到这个页面中。
另外一个要说明的是,在设置cookie的时候,我使用了一个setMaxAge(6000)的方法。这个方法是用来设置cookie的有效期,单位是秒。如果不使用这个方法或者参数为负数的话,当浏览器关闭的时候,这个cookie就失效了。在这里我给了很大的值(1000分钟),导致的行为是:当你关闭浏览器(或者关机),下次再打开浏览器访问刚才的应用,只要在1000分钟之内,就不需要再登录了。我这样做是下面要介绍的桌面SSO中所需要的功能。
其他的方法更加简单,这里就不多解释了。
3.2.2具有SSO功能的web应用源代码解析
要实现WEB-SSO的功能,只有身份认证服务是不够的。这点很显然,要想使多个应用具有单点登录的功能,还需要每个应用本身的配合:将自己的身份认证的服务交给一个统一的身份认证服务-SSOAuth。SSOAuth服务中提供的各个方法就是供每个加入SSO的Web应用来调用的。
一般来说,Web应用需要SSO的功能,应该通过以下的交互过程来调用身份认证服务的提供的认证服务:
- Web应用中每一个需要安全保护的URL在访问以前,都需要进行安全检查,如果发现没有登录(没有发现认证之后所带的cookie),就重新定向到SSOAuth中的login.jsp进行登录。
- 登录成功后,系统会自动给你的浏览器设置cookie,证明你已经登录过了。
- 当你再访问这个应用的需要保护的URL的时候,系统还是要进行安全检查的,但是这次系统能够发现相应的cookie。
- 有了这个cookie,还不能证明你就一定有权限访问。因为有可能你已经logout,或者cookie已经过期了,或者身份认证服务重起过,这些情况下,你的cookie都可能无效。应用系统拿到这个cookie,还需要调用身份认证的服务,来判断cookie时候真的有效,以及当前的cookie对应的用户是谁。
- 如果cookie效验成功,就允许用户访问当前请求的资源。
以上这些功能,可以用很多方法来实现:
- 在每个被访问的资源中(JSP或Servlet)中都加入身份认证的服务,来获得cookie,并且判断当前用户是否登录过。不过这个笨方法没有人会用:-)。
- 可以通过一个controller,将所有的功能都写到一个servlet中,然后在URL映射的时候,映射到所有需要保护的URL集合中(例如*.jsp,/security/*等)。这个方法可以使用,不过,它的缺点是不能重用。在每个应用中都要部署一个相同的servlet。
- Filter是比较好的方法。符合Servlet2.3以上的J2EE容器就具有部署filter的功能。(Filter的使用可以参考JavaWolrd的文章http://www.javaworld.com/javaworld/jw-06-2001/jw-0622-filters.html)Filter是一个具有很好的模块化,可重用的编程API,用在SSO正合适不过。本样例就是使用一个filter来完成以上的功能。
package SSO; import java.io.*; import java.net.*; import java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.*; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.GetMethod; public class SSOFilter implements Filter { private FilterConfig filterConfig = null; private String cookieName="WangYuDesktopSSOID"; private String SSOServiceURL= "http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth"; private String SSOLoginPage= "http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp"; public void init(FilterConfig filterConfig) { this.filterConfig = filterConfig; if (filterConfig != null) { if (debug) { log("SSOFilter:Initializing filter"); } } cookieName = filterConfig.getInitParameter("cookieName"); SSOServiceURL = filterConfig.getInitParameter("SSOServiceURL"); SSOLoginPage = filterConfig.getInitParameter("SSOLoginPage"); } ..... ..... }
以上的初始化的源代码有两点需要说明:一是有两个需要配置的参数SSOServiceURL和SSOLoginPage。因为当前的Web应用很可能和身份认证服务(SSOAuth)不在同一台机器上,所以需要让这个filter知道身份认证服务部署的URL,这样才能去调用它的服务。另外一点就是由于身份认证的服务调用是要通过http协议来调用的(在本样例中是这样设计的,读者完全可以设计自己的身份服务,使用别的调用协议,如RMI或SOAP等等),所有笔者引用了apache的commons工具包(详细信息情访问apache 的网站http://jakarta.apache.org/commons/index.html),其中的“httpclient”可以大大简化http调用的编程。
下面看看filter的主体方法doFilter():
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { if (debug) log("SSOFilter:doFilter()"); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String result="failed"; String url = request.getRequestURL().toString(); String qstring = request.getQueryString(); if (qstring == null) qstring =""; //检查http请求的head是否有需要的cookie String cookieValue =""; javax.servlet.http.Cookie[] diskCookies = request.getCookies(); if (diskCookies != null) { for (int i = 0; i < diskCookies.length; i++) { if(diskCookies[i].getName().equals(cookieName)){ cookieValue = diskCookies[i].getValue(); //如果找到了相应的cookie则效验其有效性 result = SSOService(cookieValue); if (debug) log("found cookies!"); } } } if (result.equals("failed")) { //效验失败或没有找到cookie,则需要登录 response.sendRedirect(SSOLoginPage+"?goto="+url); } else if (qstring.indexOf("logout") > 1) {//logout服务 if (debug) log("logout action!"); logoutService(cookieValue); response.sendRedirect(SSOLoginPage+"?goto="+url); } else {//效验成功 request.setAttribute("SSOUser",result); Throwable problem = null; try { chain.doFilter(req, res); } catch(Throwable t) { problem = t; t.printStackTrace(); } if (problem != null) { if (problem instanceof ServletException) throw (ServletException)problem; if (problem instanceof IOException) throw (IOException)problem; sendProcessingError(problem, res); } } }
doFilter()方法的逻辑也是非常简单的,在接收到请求的时候,先去查找是否存在期望的cookie值,如果找到了,就会调用SSOService(cookieValue)去效验这个cookie的有效性。如果cookie效验不成功或者cookie根本不存在,就会直接转到登录界面让用户登录;如果cookie效验成功,就不会做任何阻拦,让此请求进行下去。在配置文件中,有下面的一个节点表示了此filter的URL映射关系:只拦截所有的jsp请求。
<filter-mapping>
<filter-name>SSOFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-name>SSOFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
下面还有几个主要的函数需要说明:
private String SSOService(String cookievalue) throws IOException { String authAction = "?action=authcookie&cookiename="; HttpClient httpclient = new HttpClient(); GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue); try { httpclient.executeMethod(httpget); String result = httpget.getResponseBodyAsString(); return result; } finally { httpget.releaseConnection(); } } private void logoutService(String cookievalue) throws IOException { String authAction = "?action=logout&cookiename="; HttpClient httpclient = new HttpClient(); GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue); try { httpclient.executeMethod(httpget); httpget.getResponseBodyAsString(); } finally { httpget.releaseConnection(); } }
这两个函数主要是利用apache中的httpclient访问SSOAuth提供的认证服务来完成效验cookie和logout的功能。
其他的函数都很简单,有很多都是我的IDE(NetBeans)替我自动生成的。
发表评论
-
(转)替代传统事务的并发建议
2016-04-27 00:18 944增删改查是大部分框架 ... -
java 实现HTTP PROXY
2012-12-06 17:21 7577日常应用中使用过很多次代理,主要停留在配置级别。 近期无意看 ... -
实现Web程序的自动登录
2011-08-15 22:27 4159有很多 Web程序中第一次登录后,在一定时间内(如 2个小 ... -
APACHE实现负载均衡
2011-08-09 12:58 1294随 着访问量的不断提高,以及对响应速度的要求,进行负载均衡设 ... -
axis2调用带Authentication认证的webservice
2011-07-22 12:22 1860package com.wujianjun.axis2.cli ... -
java实现简单的单点登录(5)
2011-05-27 13:13 2130下面是登录模块DesktopSSOLoginModul ... -
java实现简单的单点登录(4)
2011-05-27 13:04 10141下面是登录模块DesktopSSOLoginModul ... -
java实现简单的单点登录(2)-Web SSO 的样例
2011-05-27 12:53 44173.1 Web SSO 的样例 根据上面的原理,我 ... -
java实现简单的单点登录(1)
2011-05-27 12:51 2380java实现简单的单点登录 摘要:单点登录 ... -
SSO相关问题总结
2011-05-20 16:30 17231 概述 对于单 ... -
HttpClient学习整理
2011-05-20 16:20 2624HttpClient 学习整理 HTTP ... -
百万级访问量网站的技术准备工作
2011-01-03 18:57 1077当今从纯网站技术上来 ... -
CAP理论,ACID和BASE
2010-12-30 00:59 1602分布式领域CAP理论:Consistency(一致性)、Ava ... -
(转)集群、分布式你想好怎么用了吗?
2010-11-07 22:13 1180做互联网、做电子商务,我们都盼望着用户数和访问量不断的攀升,这 ... -
(转)Quartz CronTrigger最完整配置说明
2010-07-14 16:06 2588Quartz CronTrigger最完整 ... -
(转)单点登陆体系结构
2010-05-31 15:08 13131.系统实现原理 用户在访问系统组件中的任何一个页面,系统都 ... -
用户权限管理模型
2010-02-04 17:57 3784前言: 权限往往是一个 ... -
OSCache使用指南
2010-02-01 21:20 1124OSCache是当前运用最广的缓存方案,JBoss,Hiber ... -
在Linux平台下部署Java web环境和发布Java web程序
2009-07-15 20:57 4888在Linux平台下部署Java web环境和发布Java we ...
相关推荐
1,通过session会话来判断 2,实现单点登录
JAVA 实现单点登录功能 ! 包含 所有的详细文档 ! 试用手册值得学习
在提供的压缩包"最新java实现简单的单点登录.doc"中,可能包含了关于如何使用Java Web和Spring Security实现SSO的具体步骤、配置代码示例和常见问题解答等内容。读者可以通过阅读这份文档,进一步了解和学习如何在...
基于Java中CAS的单点登录,有服务端的所有源码,将tomcat目录下的所有资源直接拷到Tomcat服务中间件的webapp目录下,阅读tomcat-webapp中的read.txt文档,查看使用说明,适用于第一次开发CAS单点登录的同学们,简单...
间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式...
单点登录(Single Sign-...以上就是Java实现单点登录的一些关键知识点,每个方面都需要深入了解和恰当配置,以构建一个安全、高效的SSO系统。实际开发过程中,还需要结合业务场景,考虑性能、扩展性和用户体验等因素。
Java跨域单点登录(Single Sign-On,SSO)实现是一项关键的系统集成技术,它允许用户在多个应用系统中只需登录一次,就能访问所有相互信任的应用系统,无需再次进行身份验证。本项目代码着重展示了如何在Java环境中...
3. 使用 Java EE 实现单点登录系统。 Java 实现单点登录的应用场景包括: 1. 企业应用集成(EAI):单点登录系统可以应用于企业应用集成中,以降低管理的消耗和提高安全性。 2. 面向服务的架构(SOA):单点登录...
跨服务器登录验证(单点登录SSO)的过程和Java实现 跨服务器登录验证(单点登录SSO)是指用户只需要登录一次便可以访问多个相关的应用系统的机制。这种机制可以提高用户体验和系统安全性。下面我们将介绍跨服务器...
在Java中实现微博的单点登录(Single Sign-On, SSO)功能,涉及到的主要步骤包括注册应用、获取授权码、交换访问令牌、获取用户信息等。下面我们将详细探讨这些过程。 1. **注册应用**: 在开始实现之前,你需要在...
在 Java 中实现单点登录需要使用到 Jwt(JSON Web Tokens),Jwt 是一种基于 Token 的身份验证机制,可以与 SSO 一起使用,但并不是 SSO 的必要组成部分。 首先,我们需要配置 SecurityConfig 类,该类是 Spring ...
单点登录(Single Sign On,简称SSO)是一种身份验证机制,允许用户在一次登录后,无需再次输入凭证即可访问多个相互信任的应用系统。在Java环境下实现SSO,可以为企业的信息化管理提供便利,减少用户的登录操作,...
本案例聚焦于使用Apache Shiro、Spring、Spring Data以及Redis来实现单点登录功能,下面将详细解释这些组件以及它们如何协同工作。 **Apache Shiro** Apache Shiro是一款轻量级的安全框架,提供了认证、授权、会话...
它通过共享Session和Cookie来实现单点登录。在Shiro中,可以通过配置Realm(域)来对接不同的认证源,如数据库、LDAP、CAS等。 4. **JWT(JSON Web Token)**: JWT是一种开放标准,用于在网络应用之间安全地传输...
利用springMvc 实现的简单的单点登录Demo,内含三个小Mavn项目分别是 1、认证中心SSOServer 2、子系统1SSOClient1 3、子系统2SSOClient2 文章请参考 http://blog.csdn.net/qq_31183297/article/details/79419222
http://www.blogjava.net/xcp/archive/2010/04/13/318125.html 页面的源码地址无法访问,我在其他地方找到了。可以运行的三个简单应用,配置完成后可以实现单点登录,供初学者研究其原理。
Java实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC...
CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用,研究如何采用 CAS 实现轻量级单点登录解决方案。 CAS 是 Yale 大学发起的...
jsp实现RXT单点登录,单点登录要求在OA服务器安装Server SDK开发包,同时需要配置RTX服务器安装目录下的AppConnConfig.xml文件,把OA服务器的IP地址加进来,例如OA服务器地址为172.30.21.20,配置如下所示: ...
研究者赵向梅在其论文《基于Java EE的单点登录技术研究与实现》中,设计并仿真实现了这两种单点登录系统,并证明了该系统能够有效解决当前Web应用系统面临的登录问题。通过使用Java EE平台的特性,实现了一个高效、...