Sso-server模块、System-a、System-b模块都完成了,还有疑问的请参看:
单点登录-六-模块Sso-server
单点登录-七-模块System-a
单点登录-八-模块System-b
1.首先,使用redis可视化工具保证redis的0号库没有任何数据,然后启动多个服务,


2.为了跨域,修改host,默认Windows路径是C:\Windows\System32\drivers\etc,配置三个域名,我是使用了SwitchHost工具,记得以管理呀身份运行,无论是用软件还是修改本地,软件可以直接switchhosts官网下载,这里我就不提供了,是免费的,


3.运行路径,直接浏览器输入aa.test.com:9085/home,由于我上传不了视频,就没法演示这个变化了,输入路径后会自动跳转到登录页面,uuid就是根据预处理里面写的获取的session的id,

4.随便输入什么,只要用户名和密码一致就行,


5.查看redis,是否生成了ticket,

6.登录b系统,也是在浏览器输入bb.test.com:9085/home,这里就不会进行跳转,而是直接后台验证,验证通过,直接返回页面,

7.对比两图,可以看出JSESSIONID的值是不同的,而A系统的uuid就是JSESSIONID,而b系统的uuid,ticket和A系统是相同的,这就简单实现了单点登录,
8.随便在哪个系统点击退出登录,然后马上看redis,可以看到数据已经被清空,再查看a系统的页面,一刷新又跳转到了登录页面,因为ticket已经为null,所以又开始走重定向路径,



9.基本完成那就开始考虑安全问题,虽然我验证的时候已经考虑了,其实在checkTicket接口是做了安全措施,就是每次验证就删除旧的ticket,生成新的ticket,并且按理说cookie只是保存当前浏览器,其他地方是不一样的,但是不可否认有的人就是可以获取到,那么就需要对cookie加密,我觉得只对ticket加密即可,这里提供一下,在保存ticket到cookie的时候加密,在获取cookie中的ticket时候解密,这是来源网上的AES方法,
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 57 58 59 60
|
public class EncryptUtil { public static final String SALT = "1io10fdgadfjvower389fhday29834aguourfwpg0w82dllfkfadf";
private static final String AES_SALT = "g^&*g%^F766R&PIpGY&%yg%yt$^RyfU&UT*ugyTR^R^uf&&";
public static String AESEncode(String content) throws IllegalBlockSizeException { try { KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(128, new SecureRandom(AES_SALT.getBytes())); SecretKey original_key = keygen.generateKey(); byte[] raw = original_key.getEncoded(); SecretKey key = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] byte_encode = content.getBytes("utf-8"); byte[] byte_AES = cipher.doFinal(byte_encode); return new BASE64Encoder().encode(byte_AES); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | UnsupportedEncodingException e) { e.printStackTrace(); } return null; }
public static String AESDecode(String content) { try { KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(128, new SecureRandom(AES_SALT.getBytes())); SecretKey original_key = keygen.generateKey(); byte[] raw = original_key.getEncoded(); SecretKey key = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] byte_content = new BASE64Decoder().decodeBuffer(content);
byte[] byte_decode = cipher.doFinal(byte_content); return new String(byte_decode, "utf-8"); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | IOException | BadPaddingException e) { e.printStackTrace(); } return null; } }
|
10.由于感觉写的有点乱,给一下项目的git地址,有问题可以留言,
1
| https://gitee.com/zllwsy/Commont/tree/master/Springboot-sso
|
11.有细心的可以发现,其实还有个模块没有使用,那就是System-gateway,其实我本身是用了,但是发现我就一个请求,完全用不着,给一下yml配置文件,
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
| server: port: 9087 spring: cloud: nacos: discovery: enabled: true server-addr: xxx.xxx.xxx.xxx:8848 namespace: 5ced42ff-fe7d-418e-8aab-1c3e0bcaf487
gateway: discovery: locator: enabled: true routes: - id: route_a uri: https://aa.test.com:9085 predicates: - Path=/home
application: name: System-gateway
|
12.也可以在启动器里面添加一个配置的bean,
1 2 3 4 5 6 7 8
| @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.path("/home") .uri("https://aa.test.com:9085") ).build(); }
|
13.顺便提供一下Springcloud gateway的官方文档的地址路径,
1
| https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
|
总结:
单点登录完成,有点瑕疵,勉强完成,还是自己的底蕴太差,很多考虑不周全,如果后面有时间我会更新单点登录,使用CAS来做一做,有问题还请各位大佬提出,小弟在此感谢了。