SpringBoot实例:医院统一信息平台(spring ses

2018-11-08  本文已影响211人  碧波之心

SpringBoot2的session使用与1有点区别。如果根据1的组件包含使用redis是会报异常的。没有细研究,先解决问题。
在SpringBoot1中要使用redis session如下包含:

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

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

而SpringBoot2中:

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

redis配置也有点区别:
SpringBoot1:

spring:
  redis:
    # redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
    database: 9
    # redis服务器地址(默认为localhost)
    host: localhost
    # redis端口(默认为6379)
    port: 6379
    # redis访问密码(默认为空)
    password: 
    # redis连接超时时间(单位为毫秒)
    timeout: 3600000
    # redis连接池配置
    pool:
      # 最大可用连接数(默认为8,负数表示无限)
      max-active: -1
      # 最大空闲连接数(默认为8,负数表示无限)
      max-idle: 200
      # 最小空闲连接数(默认为0,该值只有为正数才有作用)
      min-idle: 0
      # 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
      max-wait: -1

SpringBoot2:

spring:
  redis:
    # redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
    database: 9
    # redis服务器地址(默认为localhost)
    host: localhost
    # redis端口(默认为6379)
    port: 6379
    # redis访问密码(默认为空)
    password: 
    # redis连接超时时间(单位为毫秒)
    timeout: 3600000
    # redis连接池配置
    jedis:
      pool:
        # 最大可用连接数(默认为8,负数表示无限)
        max-active: -1
        # 最大空闲连接数(默认为8,负数表示无限)
        max-idle: 200
        # 最小空闲连接数(默认为0,该值只有为正数才有作用)
        min-idle: 0
        # 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
        max-wait: -1

如上包含与配置完成后,加入“@EnableRedisHttpSession”可以使用spring session。集群情况下,session也是想通的。即用户服务中保存数值到session中,其它服务可以访问到同一个session。

spring security与spring session

使用SessionRegistry

  1. 创建bean
    @Bean
    public SessionRegistry sessionRegistry(){
        SessionRegistry sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }
  1. 配置sessionManagement
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home", "/oauth/token", "/oauth/authorize").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .sessionManagement()
                .maximumSessions(1)
                .sessionRegistry(sessionRegistry())
                .and().and()
            .logout()
                .permitAll();
        http.addFilterBefore(mobileCodeAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
        // @formatter:on
    }
  1. 使用SessionRegistry
    @Autowired
    private SessionRegistry sessionRegistry;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        List<Object> principals = sessionRegistry.getAllPrincipals();
        System.out.println(principals.size());
        for (Object principal : principals) {
            System.out.println(principal);
            System.out.println(principal instanceof String);
        }
        return "hello";
    }

这里只是做记录,项目中没有使用SessionRegistry

获取当前登录用户

spring scurity配合spring session获取当前登录的用户有三种方法(还有其它方法的话,还望留言告知):

    @RequestMapping(value = "/demo")
    @ResponseBody
    public String username(Principal principal, HttpSession session) {
        System.out.println("1:" + principal.getName());
        Object springSecurityContext = session.getAttribute("SPRING_SECURITY_CONTEXT");
        if (springSecurityContext instanceof SecurityContext) {
            SecurityContext sc = (SecurityContext) springSecurityContext;
            Authentication authentication = sc.getAuthentication();
            if (!(authentication instanceof AnonymousAuthenticationToken)) {
                System.out.println("2:" + authentication.getName());
            }
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (null != authentication) {
            if (!(authentication instanceof AnonymousAuthenticationToken)) {
                System.out.println("3:" + authentication.getName());
            }
        }
        return principal.getName();
    }

其中principal.getName()与authentication.getName()打印出来的结果是一样的。而第三种方法是可以使用在service中的。可以到service中获取当前登录用户,这样就不必每个API中都带上principal或session参数了。因为这里session是保存在redis中。所以,即使是在集群(微服务)中的各个服务都可以这样获取当前登录的用户。

上一篇下一篇

猜你喜欢

热点阅读