情况。我们正在使用带有JWT的Spring OAuth2保护多重路径,例如,我们正在使用多个客户端
客户端:admin-保护/ adminstuff,但无法访问/ swagger-ui
客户端:昂首阔步-保护/ swagger-ui,但无法访问/ adminstuff
代码:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(AuthorizationServerConfig.class);
@Autowired
private TokenStore tokenStore;
@Resource(name = "cliente")
private ClientDetailsService clientes;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
logger.info( "ClientDetailsServiceConfigurer" );
configurer.withClientDetails( clientes );
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
{
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.tokenEnhancer(enhancerChain)
.exceptionTranslator(loggingExceptionTranslator());
}
@Bean
public WebResponseExceptionTranslator<OAuth2Exception> loggingExceptionTranslator() {
return new DefaultWebResponseExceptionTranslator() {
@Override
public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {
// This is the line that prints the stack trace to the log. You can customise
// this to format the trace etc if you like
e.printStackTrace();
// Carry on handling the exception
ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
HttpHeaders headers = new HttpHeaders();
headers.setAll(responseEntity.getHeaders().toSingleValueMap());
OAuth2Exception excBody = responseEntity.getBody();
return new ResponseEntity<>(excBody, headers, responseEntity.getStatusCode());
}
};
}
}
所有这些代码都位于一个授权微服务上,该服务在mysql数据库中具有我们所有的客户端凭据。
因此在另一个微服务中,我们有多个“ ResourceServerConfigurerAdapter”,就像这样
@Configuration
@EnableResourceServer
@Order(8)
public class AdministradoresResourceServerConfiguration extends ResourceServerConfigurerAdapter
{
Logger logger = LoggerFactory.getLogger(AdministradoresResourceServerConfiguration.class);
@Value("${security.unprotected-paths}")
private String[] unProtectedPaths;
@Value("${security.jwt.administradores-resource-id}")
private String administradores;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(administradores);
}
@Override
public void configure(HttpSecurity http) throws Exception {
logger.info("AdministradoresResourceServerConfiguration");
http.exceptionHandling().authenticationEntryPoint(new
AuthException()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable().requestMatchers().and()
.authorizeRequests()
.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
"/configuration/security", "/swagger-ui.html", "/webjars/**").denyAll()
.antMatchers(unProtectedPaths).permitAll()
.anyRequest().authenticated();
}
}
@Configuration
@EnableResourceServer
@Order(7)
public class SwaggerResourceServerConfiguration extends ResourceServerConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(SwaggerResourceServerConfiguration.class);
@Value("${security.unprotected-paths}")
private String[] unProtectedPaths;
@Value("${security.jwt.swagger-resource-id}")
private String swagger;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(swagger);
}
@Override
public void configure(HttpSecurity http) throws Exception {
logger.info("SwaggerResourceServerConfiguration");
http.exceptionHandling().authenticationEntryPoint(new
AuthException()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().requestMatchers().and()
.authorizeRequests()
.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
"/configuration/security", "/swagger-ui.html", "/webjars/**")
.hasAuthority("proyecto:web:swagger:admin")
.antMatchers(unProtectedPaths).permitAll()
.anyRequest().denyAll()
.and().csrf().disable();
}
}
但是显然,配置只需要一个,希格顺序, 我们已经尝试过
像这样的东西,结果相同,一个东西覆盖另一个东西,或者至少是弹簧靴只占一个
@Value("${security.unprotected-paths}")
private String[] unProtectedPaths;
@Value("${security.jwt.swagger-resource-id}")
private String swagger;
@Value("${security.jwt.administradores-resource-id}")
private String administradores;
@Bean
protected ResourceServerConfiguration aminis() {
ResourceServerConfiguration resource = new ResourceServerConfiguration() {
public void setConfigurers(List<ResourceServerConfigurer> configurers) {
super.setConfigurers(configurers);
}
};
resource.setConfigurers(Arrays.<ResourceServerConfigurer>asList(new
ResourceServerConfigurerAdapter() {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(administradores);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(new
AuthException()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable().requestMatchers()
.and().authorizeRequests()
.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
"/configuration/security", "/swagger-ui.html", "/webjars/**")
.hasAuthority("proyecto:web:swagger:admin-admin")
.antMatchers(unProtectedPaths).permitAll().anyRequest()
.authenticated();
}
}));
resource.setOrder(4);
return resource;
}
@Bean
protected ResourceServerConfiguration swageris() {
ResourceServerConfiguration resource = new ResourceServerConfiguration() {
public void setConfigurers(List<ResourceServerConfigurer> configurers) {
super.setConfigurers(configurers);
}
};
resource.setConfigurers(Arrays.<ResourceServerConfigurer>asList(new
ResourceServerConfigurerAdapter() {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(swagger);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(new
AuthException()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().requestMatchers().and()
.authorizeRequests()
.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
"/configuration/security", "/swagger-ui.html", "/webjars/**")
.hasAuthority("proyecto:web:swagger:admin-
swagger").antMatchers(unProtectedPaths).permitAll()
.anyRequest().denyAll();
}
}));
resource.setOrder(5);
return resource;
}
我们的POM中有这个
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.6</version>
</dependency>
<!-- ________ SEGURIDAD ________ -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<!-- ________ HATEOAS ________ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<!-- ________ JPA ________ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- ________ THYMELEAF ________ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
注意: 我们不能使用“ AuthorizationServerConfig”,因为它失去了授权微服务的维护
如此:
问题。我们如何在微服务基础结构中支持多个客户端ID
谢谢大家!