java - session 验证 - Spring Security with Microservices

标签 java spring-security redis spring-cloud spring-cloud-security

我当前的 Web 应用程序架构有一个网关服务器,可以协调一堆微服务,如果给定原则通过身份验证,授权就会在网关发生,他们可以与一些下游服务对话。

下游服务获取所需的数据以识别给定的经过身份验证的客户端。然而, Spring 证券违约行为开始出现并引发预期:

org.springframework.security.access.AccessDeniedException: Access is denied

鉴于我可以在任何给定的微服务中使用 session ID 和 + XSRF token 来验证用户是否已通过身份验证并知道哪个用户已登录(我目前正在使用 Http Basic)。

我的问题 是否有一种更简单/声明性的方法可以用来代替必须向每个微服务添加过滤器来覆盖 spring securities 默认行为? (参见我的示例伪代码)

请参阅附图: 体系结构。 enter image description here

资源服务器的 Spring Web 安全配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public SessionRepository<ExpiringSession> sessionRepository() {
        return new MapSessionRepository();
    }


    @Bean
    HeaderHttpSessionStrategy sessionStrategy() {
        return new HeaderHttpSessionStrategy();
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
              .and().authorizeRequests().anyRequest().authenticated();


        final SessionRepositoryFilter<ExpiringSession> sessionRepositoryFilter = new SessionRepositoryFilter<ExpiringSession>(
                sessionRepository());
        sessionRepositoryFilter
                .setHttpSessionStrategy(new HeaderHttpSessionStrategy());

        http.addFilterBefore(sessionRepositoryFilter,
                ChannelProcessingFilter.class).csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);

    }

    public SessionRepository<ExpiringSession> getSessionRepository(){
        return sessionRepository();
    }

}

资源微服务的 header 值:

KEY: cookie VALUE: XSRF-TOKEN=[token_value]; SESSION=[session_value]
KEY: x-requested-with VALUE: XMLHttpRequest
KEY: x-auth-token VALUE: a32302fd-589b-42e1-8b9d-1991a080e904
...

计划的方法(伪代码)将一个新过滤器附加到 spring securities 过滤器链,如果给定的标志为真,则允许访问安全端点。

**
 * A custom filter that can grant access to the current resource
 * if there is a valid XSRF-TOKEN and SESSION present in the shared
 * session cache.
 */
public class CustomAuthenticationFilter extends AnAppropriateFilterChainFilter {

    @Autowired
    SessionRepository sessionRepository;


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {



        boolean csrfTokenExists = sessionRepository.findByCsrfTokenId(request);

        boolean sessionExists = sessionRepository.findBySessionId(request);

        if (csrfTokenExists && sessionExists) {
            // everything is okay
        } else {
            // invalidate the request as being authenticated
            throw new InsufficientAuthenticationException("Invalid csrf + session pair");

        }

    }


}

最佳答案

将我的 spring boot parent 更新到 2.0.1 Release 并将我的 spring cloud 版本更改为 Finchley 后,spring boot 解决了这个问题。

注意 session repositoryHttpSessionStrategy 不是必需的,

HttpSessionStrategy 自 spring session 成为 spring session core 以来现在已贬值。

使用 redisspring boot 的外部化配置,所有依赖系统都会自动使用该缓存来验证有效 session ,前提是您在类路径上具有 spring 安全性。

请注意,如果您正在使用网关模式和 Zuul Proxy,请确保您的代理路由在您的应用 YML/properties 中包含 sensitive-headers: 属性,请参阅以下示例:

示例 auth + 网关使用共享 session 缓存的 Springboot 配置。

Auth Gateway

spring:
  profiles: dev
  redis:
    host: localhost
    port: 6379
  session:
    store-type: redis

server:
  port:   8080

zuul:
  routes:
    # local routes
    api:
      url: forward:/api
      path: /api/**
      sensitive-headers:
    # cloud-resource
    resource:
      url: http://localhost:9002
      path: /resource/**
      strip-prefix: false
      sensitive-headers:

proxy:
  auth:
    routes:
      resource: passthru
      ui: none
      api: passthru

security:
  sessions: ALWAYS

Some Secured Resource Server

spring:
  profiles: dev
  redis:
    host: localhost
    port: 6379
  session:
    store-type: redis
  security:
    enabled: false

server:
  port:  9002

security:
  # Never create a session, but if one exists use it
  sessions: NEVER
  # don't display the auth box
  basic:
    enabled: false

management:
  security:
    enabled: false

关于java - session 验证 - Spring Security with Microservices,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49619327/

相关文章:

java - 如何使用 Spring MVC 和 Java 获取基本的 HTTP 身份验证数据

ruby-on-rails - 如何设置redis连接

java - android listview loadmore按钮与xml解析

java - RichFaces 4.2 转发到新页面,h :commandLink

java - JDBC 结果集 Type_Scroll_Sensitive

java - 测试期间自动创建 Spring 实体 "authorities"

Swift 中的 Java 风格枚举

java - spring session 初始化错误

redis - 如何将 redis CrudRepository 关联到数据库

Spring数据Redis HGETALL操作