分布式系统统一登录的实现

筅森魡賤 提交于 2019-11-25 19:04:35

一、 运用Redis缓存将Token存入缓存;

将 session 全部存放到 Redis 中,Redis 全局管理数据,因为独特的 key 过期时间特性,对应 session 的过期特性,也很般配。另外,Redis 比较轻量,性能也很好。

用户在登录的时候如果通过鉴权体系的鉴定,可以生成 Token 数据,以 Token 作为键名,用户登录信息作为值,写入到 Redis 中,设置过期时间,并将 Token 写入 cookie 中。用户下次进行敏感操作的时候,通过拦截器判断用户请求头中 cookie 的 token 字段是否能在 Redis 中查询到数据。如果能查询到,就允许用户进行操作并刷新登录有效期,否则就返回登录 URL,这样一个分布式系统的单点登录系统就实现了

二、配置负载均衡策略时使用源地址哈希法。相同的IP客户端,如果服务器列表不变,将映射到同一个后台服务器进行访问

一致性哈希算法与C++实现

三、Spring Security的session共享

1.构建一个SpringSecurity应用
1.1Spring Boot 版本是 2.0.4.RELEASE,引入security启动器
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
1.2 整体部分包括认证和授权,即你是谁,你有哪些权限
  • authentication 的思路是用户传过来的表单数据,username和password 在spring security 由Authentication 封装, 从 SecurityContextHolder 中获取 SecurityContext 再获取 Authentication,即可获取到用户提供的认证消息

而UserDetail是数据库测的用户信息,保存着密码和其它更详细的用户信息,实现UserDetailsService 的方法即根据

用户名从数据库中获取UserDetail,这就是大致的认证过程,如果认证失败,抛出相应的异常,如果认证成功进行鉴权。

  • authorization思路授权过程是,获取当前请求的url,从数据库中根据此url查询出访问此url的角色有哪些 ,然后将用户

当前的角色和请求该路径应当具有的角色进行比较,如果用户的角色在其中,则鉴权通过,否则抛出异常 。

1.3 Spring Security是如何实现的。在servlet的环境中是使用Filter实现的

在引入Spring Security 依赖的时候就会在META-INF/spring.factory 实例化SecurityFilterAutoConfiguration ,将DelegatingFilterProxy 过滤器 以 “springSecurityFilterChain“的beanName注册到“/”到servlet容器中,DelegatingFilterProxy

本身什么也不做,包含FilterChainProxy对象,而FilterChainProxy对象里有 private List filterChains ,

真正干活的是SecurityFilterChain 实例,SecurityFilterChain 中 有List getFilters() 方法,真正过滤的是这里的Filter

这里大致有SecurityContextPersistenceFilter、HeaderWriterFilter、LogoutFilter、UsernamePasswordAuthenticationFilter等filter ,这种代理的方式注入filter,使Filter不至于十分冗长和复杂

1.4 数据库大致介绍

用户表 :用户名,头像,中文名,加密过的密码

角色表:角色名,角色中文名名 角色名以“ROLE_”开头,例如ROLE_admin

用户角色中间表:双方的id

菜单表 :正则形式的url ,其它数据,自关联也可以

角色菜单中间表:双发的id

如果没有配置角色,即登入就可以访问了

1.5 具体使用流程

提供账号和密码,密码或账号不对时不能登入

登入用户后,访问对应的资源url,没有权限时不能访问,即做到了权限控制,而且这种权限控制是基于数据可配置,十分灵活

1.6 使用的注意事项 登入成功后,还能记住用户信息 ,使用的是 cookie 和session ,但nginx部署springBoot集群时,会导致

轮询访问所得到的session不同,

nginx核心配置

    #测试security中的session机制;
    upstream delegating_server{
        server 127.0.0.1:8082  weight=20;
        server 127.0.0.1:8083  weight=5;
    }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        
        location /cache {
            proxy_pass   http://cache_server/;
            root   html;
            index  index.html index.htm;
        }

        location /security {
        #做负载均衡时,其中一个节点挂掉,默认是1分钟后转发给其它的节点proxy_connect_timeout可以更改时长
            proxy_pass   http://delegating_server;
            root   html;
            index  index.html index.htm;
            proxy_set_header   Host             $host;  
            proxy_set_header   X-Real-IP        $remote_addr;  
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;  
            proxy_connect_timeout 3; 
            proxy_read_timeout 1; 
            proxy_send_timeout 1; 
        }

当停掉一个springBoot实例后,就可以恢复正常,

2.使用redis实现session共享

引入依赖

         <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

redis配置 一下,此处注意一下,spring 默认使用lettuce 连接redis服务

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!