SSO实现方案
2014-06-03 10:12
197 查看
一、单点登录介绍
单点登录的机制比较简单,如下图所示:
1、当用户第一次访问应用系统的时候,因为用户还没有登录,应用系统会向认证系统请求ticket。
2、认证系统接收到ticket的请求,如果用户已经登录则返回ticket,进行第4步操作,如果用户还没有登录,则引导到认证系统的登录页面。
3、用户提交用户名密码,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据(ticket)到应用系统
4、应用系统接收到ticket,向认证系统发起验证ticket的请求
5、认证系统通过ticket的验证,并删除掉保存在认证系统的ticket,然后返回用户信息
6、应用系统接收到返回的用户信息,然后通过本地认证,返回受保护资源给用户
二、认证系统的实现
在认证系统中接入应用系统。
Java
认证系统的登录认证,如果只是登录到认证系统,则进去认证系统的首页,如果请求中包含appId和callback参数的,则说明是应用系统的登录请求,则需要返回到应用系统,并且返回ticket。generateTicket()是生成ticket的,一般是一串加密串,我这里为了简单起见直接使用UUID。注:这里还返回了sessionId,因为下面的应用系统请求验证ticket的时候,使用的HttpClient,发送的是http请求,没有sessionId,则读取不到认证系统中的session。Java
认证系统接收应用系统的验证ticket请求,并返回登录用户的信息
Java
三、应用系统实现[align=left] 用户访问应用系统的受保护资源,如果用户还未在本应用系统登录过,应用系统会向认证系统发起获取ticket的请求[/align][align=left][/align]Java
应用系统接收到认证系统返回的ticket,然后发起验证ticket的请求
Java
四、示例下载及运行说明
示例下载地址:http://download.csdn.net/download/yangpingzhun/5476937
示例程序需要maven支持,所以需要运行的示例的,需要安装maven;在hosts文件中配置一条域名解析(127.0.0.1 www.server.com www.client.com),然后运行test源文件夹下的JettyServer和JettyClient即可,测试url:http://www.client.com:8081/client/admin.htm
单点登录的机制比较简单,如下图所示:
1、当用户第一次访问应用系统的时候,因为用户还没有登录,应用系统会向认证系统请求ticket。
2、认证系统接收到ticket的请求,如果用户已经登录则返回ticket,进行第4步操作,如果用户还没有登录,则引导到认证系统的登录页面。
3、用户提交用户名密码,认证系统进行身份效验,如果通过效验,应该返回给用户一个认证的凭据(ticket)到应用系统
4、应用系统接收到ticket,向认证系统发起验证ticket的请求
5、认证系统通过ticket的验证,并删除掉保存在认证系统的ticket,然后返回用户信息
6、应用系统接收到返回的用户信息,然后通过本地认证,返回受保护资源给用户
二、认证系统的实现
在认证系统中接入应用系统。
Java
1234 | private static Map<String, String> clientMap = new HashMap<String, String>();static{ clientMap.put("1000" , "client1000" );} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @RequestMapping("loginAuth.htm") publicvoidloginAuth(HttpServletRequestrequest,HttpServletResponseresponse,StringuserId)throwsIOException{ request.getSession().setAttribute("userId",userId); request.getSession().setAttribute("ticketMap",newHashMap<String,String>()); Stringcallback=request.getParameter("callback"); StringappId=request.getParameter("appId"); //如果是应用系统过来的登录验证,需要返回ticket if(StringUtils.hasText(callback)&&StringUtils.hasText(appId)){ Stringticket=generateTicket(appId,request); Stringurl=callback+"?ticket="+ticket; StringsessionParam=getSessionId(request); if(StringUtils.hasText(sessionParam)){ url+="&"+sessionParam; } response.sendRedirect(url); }else{ response.sendRedirect("/server/admin.htm"); } } |
Java
1234567891011121314151617181920212223242526272829303132 | @ResponseBody@RequestMapping("validTicket.htm" )public Object validTicket(HttpServletRequest request,HttpServletResponse response){ String appId = request.getParameter( "appId"); String ticket = request.getParameter( "ticket"); String secret = request.getParameter( "secret"); ValidReturn result = new ValidReturn(); if(clientMap .containsKey(appId)){ //验证第三方系统的是否存在 String appSecret = clientMap.get(appId); if(appSecret.equals(secret)){ //验证第三方系统的密码 Map<String, String> ticketMap = (HashMap<String, String>)request.getSession().getAttribute("ticketMap" ); if(ticketMap.containsKey(appId)){ String existTicket = ticketMap.get(appId); if(existTicket.equals(ticket)){ String userId = (String)request.getSession().getAttribute("userId" ); result.setUserId(userId); ticketMap.remove(appId); // 验证之后删除ticket } else{ result.setError( "ticket error"); } } else{ result.setError( "ticket expired"); } } else{ result.setError( "password error"); } } else{ result.setError( "app not exist"); } return result;} |
1 2 3 4 5 6 7 8 9 10 11 12 13 | @RequestMapping("admin.htm") publicStringadmin(HttpServletRequestrequest,HttpServletResponseresponse){ StringuserId=(String)request.getSession().getAttribute("userId"); if(StringUtils.hasText(userId)){ return"client/admin"; } try{ response.sendRedirect("http://www.server.com:8080/server/getTicket.htm?appId=1000&callback=http://www.client.com:8081/client/callback.htm"); }catch(IOExceptione){ e.printStackTrace(); } returnnull; } |
Java
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | @RequestMapping("callback.htm") publicvoidcallback(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{ Stringerror=request.getParameter("error"); if(StringUtils.hasText(error)){ System.out.println(error); response.sendRedirect("/client/error.htm?error="+error); }else{ Stringticket=request.getParameter("ticket");//获取ticket StringsessionId=request.getParameter("JSESSIONID");//获取 sessionid ValidReturnresult=null; try{ result=validAndGetUserId(ticket,sessionId); if(StringUtils.hasText(result.getUserId())){ request.getSession().setAttribute("userId",result.getUserId()); response.sendRedirect("/client/admin.htm"); }else{ response.sendRedirect("/client/error.htm?error="+result.getError()); } }catch(Exceptione){ e.printStackTrace(); } if(result==null){ response.sendRedirect("/client/error.htm?error=0000000"); } } } privateValidReturnvalidAndGetUserId(Stringticket,StringsessionId)throwsHttpException,IOException{ //如何获取session,获取cookies PostMethodpostMethod=newPostMethod("http://www.server.com:8080/server/validTicket.htm"); postMethod.addParameter("appId","1000"); postMethod.addParameter("secret","client1000"); postMethod.addParameter("ticket",ticket); //postMethod.addParameter("JSESSIONID",seesionId); HttpMethodParamsparam=postMethod.getParams(); param.setContentCharset("UTF-8"); postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, newDefaultHttpMethodRetryHandler(3,false)); postMethod.setRequestHeader("Cookie","JSESSIONID="+sessionId);//添加sessionId,让Server知道使用哪个Session HttpClientParamsclientParams=newHttpClientParams(); // 忽略cookie 避免 Cookie rejected 警告 clientParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES); HttpClientclient=newHttpClient(clientParams); client.executeMethod(postMethod); Header[]resHeader=postMethod.getResponseHeaders(); intresponseCode=postMethod.getStatusCode(); System.out.println("responseCode:"+responseCode); for(Headerheader:resHeader){ System.out.println(header.getName()+":"+header.getValue()); } StringreturnStr=postMethod.getResponseBodyAsString(); ValidReturnresult=newGson().fromJson(returnStr,ValidReturn.class); postMethod.releaseConnection(); returnresult; } |
示例下载地址:http://download.csdn.net/download/yangpingzhun/5476937
示例程序需要maven支持,所以需要运行的示例的,需要安装maven;在hosts文件中配置一条域名解析(127.0.0.1 www.server.com www.client.com),然后运行test源文件夹下的JettyServer和JettyClient即可,测试url:http://www.client.com:8081/client/admin.htm
相关文章推荐
- 简单的SSO方案 COOKIE实现
- Single Sign-On(SSO)单点登陆的具体实现方案
- 可跨域的单点登录(SSO)实现方案【附.net代码】
- 在特定情况下的简单SSO实现方案
- java sso 基于 cookie 实现方案 kisso
- 可跨域的单点登录(SSO)实现方案
- Single Sign-On(SSO)单点登陆的具体实现方案【转载】
- Single Sign-On(SSO)单点登陆的具体实现方案
- sso 之 搜狐单点登陆实现方案
- 实现sso 的两种方案
- 详解可跨域的单点登录(SSO)实现方案【附.net代码】
- 简单的SSO方案 COOKIE实现
- SSO 实现方案探讨
- 详解可跨域的单点登录(SSO)实现方案【附.net代码】
- [转] 可跨域的单点登录(SSO)实现方案
- cas sso ajax的jsonp实现方案总结(新浪微薄、淘宝案例分析)
- 多系统实现单点登录方案:SSO 单点登录
- [导入]在特定情况下的简单SSO实现方案
- 浏览器三种刷新方式的缓存机制-----单点登录SSO的实现原理---PHP版单点登陆实现方案