[英]Session Validation - Spring Security with Microservices
我当前用于Web应用程序的体系结构具有一个网关服务器,该服务器可以协调许多微服务,如果验证了给定的原理,它们可以与某些下游服务进行对话,则授权将在网关处进行。
下游服务将保留所需数据,以标识给定的经过身份验证的客户端。 然而,春季证券违约行为开始并引发了预期:
org.springframework.security.access.AccessDeniedException: Access is denied
鉴于我可以在任何给定的微服务中使用会话ID和+ XSRF令牌来验证用户是否已通过身份验证,并知道哪个用户已登录(我目前正在使用Http Basic)。
我的问题是,可以使用一种更简单/声明性的方法来代替必须为每个微服务添加过滤器以覆盖春季证券违约行为吗? (请参阅我的示例伪代码)
资源服务器的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();
}
}
资源微服务的标头值:
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证券过滤器链上,如果给定标志为true,则允许访问安全端点。
**
* 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父级更新为2.0.1 Release
,并将Spring Cloud版本更改为Finchley
,Spring Boot解决了该问题。
请注意,不需要session repository
和HttpSessionStrategy
,
自从春季会议成为春季会议的核心以来, HttpSessionStrategy
现在已贬值。
使用外部化的redis
和spring boot
配置,所有从属系统会自动使用该缓存来验证有效会话,前提是您在类路径上具有spring安全性。
请注意,如果您使用的是网关模式和Zuul Proxy
确保您的代理路由在应用程序YML /属性中包含sensitive-headers:
属性,请参见以下示例:
使用Springboot的示例auth +网关配置共享会话缓存。
验证网关
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
一些安全的资源服务器
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.