一.新建三个项目
1.Sso-Servet:sso服务器
2.Sso-Client1:sso客户端1
3.Sso-Client2:sso客户端2
二.hosts中添加三个域名映射
127.0.0.1 server.tiglle.com
127.0.0.1 client1.tiglle.com
127.0.0.1 client2.tiglle.com
三.修改tomcat的Server.xml配置文件,新增三个虚拟主机,分别用三个域名,运行三个项目
<Host name="server.tiglle.com" appBase="F:/MyEclipseWorkSpaces/MyEclipse-SSO/Sso-Server/WebRoot" autoDeploy="true" unpackWARs="true">
<Context docBase="/" path="/server" reloadable="true"></Context>
</Host>
<Host name="client1.tiglle.com" appBase="F:/MyEclipseWorkSpaces/MyEclipse-SSO/Sso-Client1/WebRoot" autoDeploy="true" unpackWARs="true">
<Context docBase="" path="/client1" reloadable="true"></Context>
</Host>
<Host name="client2.tiglle.com" appBase="F:/MyEclipseWorkSpaces/MyEclipse-SSO/Sso-Client2/WebRoot" autoDeploy="true" unpackWARs="true">
<Context docBase="F:/MyEclipseWorkSpaces/MyEclipse-SSO/Sso-Client2/WebRoot" path="/client2" reloadable="true"></Context>
</Host>
四.功能介绍
Sso-Server:
1.负责登陆页面的提供,登陆校验,登陆成功后写入cookie(Cookie必须设置domain的值为所有子域名都能访问到)。
2.登陆成功后重定向到请求的客户端
3.校验Cookie的有效性
Sso-Client1:
1.获取cookie并传给Sso-Server进行校验,获得校验结果,校验成功,既登陆成功,跳转到主页面。否则重定向到Sso-Server的登陆页面,并提供自己的回调地址
Sso-Client2:
1.获取cookie并传给Sso-Server进行校验,获得校验结果,校验成功,既登陆成功,跳转到主页面。否则重定向到Sso-Server的登陆页面,并提供自己的回调地址
五.代码
一.结构图(springmvc框架)
二.源码
1.LoginController:
package com.tiglle.controller;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tiglle.bean.User;
import com.tiglle.service.UserService;
@Controller
public class LoginController {
@Autowired
private UserService userService;
/**
* 到登陆页面
* @param map
* @param request
* @return
*/
@RequestMapping("/toLogin")
public String toLogin(Map<String,Object> map,HttpServletRequest request){
String callbackurl = request.getParameter("callbackurl");
map.put("callbackurl", callbackurl);
return "login";
}
/**
* 登陆
* @param request
* @param response
* @param user
* @return
*/
@RequestMapping("/login")
public String login(HttpServletRequest request,HttpServletResponse response,User user){
if(userService.checkLogin(user)){
//写入cookie
Cookie cookie = new Cookie("username",user.getUsername());
cookie.setMaxAge(300);
//tiglle.com下的子域名都能获得此cookie
cookie.setDomain(".tiglle.com");
cookie.setPath("/");
response.addCookie(cookie);
//重定向到callbackurl
return "redirect:"+user.getCallbackurl();
}
return "login";
}
/**
* 校验cookie
* @param request
* @param response
* @param cookieName
* @param CookieValue
*/
@RequestMapping("/checkCookie")
public void checkCookie(HttpServletRequest request,HttpServletResponse response,String cookieName,String cookieValue){
try {
response.getWriter().print(userService.checkCookie(cookieName, cookieValue));
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.UserService:
package com.tiglle.service;
import org.springframework.stereotype.Service;
import com.tiglle.bean.User;
@Service
public class UserService {
private User user = new User("xiaoming","123456");
public boolean checkLogin(User paramUser){
if(paramUser.getUsername().equals(user.getUsername())&¶mUser.getPassword().equals(user.getPassword())){
return true;
}
return false;
}
public String checkCookie(String name,String value){
if(name.equals("username")&&value.equals(user.getUsername())){
return "SUCCESS";
}
return "ERROR";
}
}
3.User:
package com.tiglle.bean;
public class User {
private String username;
private String password;
private String callbackurl;
public String getCallbackurl() {
return callbackurl;
}
public void setCallbackurl(String callbackurl) {
this.callbackurl = callbackurl;
}
public User() {
super();
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<!-- 开启注解模式驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 扫包 -->
<context:component-scan base-package="com.tiglle.*"></context:component-scan>
<!-- 视图渲染 jsp/freemaker/velocity-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 制定页面存放的路径 -->
<property name="prefix" value="/WEB-INF/page/"></property>
<!-- 文件的后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
6.web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<!-- Spring MVC 核心 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--以下init-param是自定义SpringMVC的配置文件的位置 -->
<!-- 可以通过contextConfigLocation来自定义SpringMVC配置文件的位置,如不指定,则默认在WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,
此时文件名必须为[<servlet-name>]-servlet.xml,否则会出错-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 拦截设置 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring MVC 核心配置结束 -->
<!-- Spring字符集过滤器 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
7.MainController:
package com.tiglle.controller;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tiglle.utils.RemoteUtil;
@Controller
public class MainController {
@RequestMapping("/main")
public String main(HttpServletRequest request,Map<String,String> map){
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
if(cookie.getName().equals("username")){
String result = RemoteUtil.getRemoteCheckCookieResult("http://server.tiglle.com/server/checkCookie", cookie.getName(), cookie.getValue());
if(result.equals("SUCCESS")){
return "main";
}
}
}
}
return "redirect:http://server.tiglle.com/server/toLogin?callbackurl=http://client1.tiglle.com/client1/main";
}
}
8.RemoteUtil:
package com.tiglle.utils;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class RemoteUtil {
public static String getRemoteCheckCookieResult(String remoteUrl,String cookieName,String cookieValue){
HttpURLConnection httpURLConnection = null;
StringBuffer sb = new StringBuffer();
try {
URL url = new URL(remoteUrl+"?cookieName="+cookieName+"&cookieValue="+cookieValue);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
InputStream is = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String temp = null;
while((temp=br.readLine())!=null){
sb.append(temp);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(httpURLConnection!=null) httpURLConnection.disconnect();
}
return sb.toString();
}
}
9.Client1和Client2的代码差不多一样
详见百度云