我正在为Spring Boot应用程序设计REST API,但是我在设计时遇到了问题。我想以前缀/project_name/v1/
启动所有REST端点。
我有数百个端点经过身份验证保护,只有一对端点无需身份验证即可访问。
这是当前状态:
Method | Endpoint | Secure
------------------------------------------------------------------
POST | /project_name/activate | accessible to everybody
GET | /project_name/activate/{id} | accessible to everybody
GET | /project_name/v1/getAllUsers/ | protected by token
GET | /project_name/v1/getUser/{id} | protected by token
POST | /project_name/v1/createUser/ | protected by token
... | /project_name/v1/... | protected by token
这是所需状态:
Method | Endpoint | Secure
------------------------------------------------------------------
POST | /project_name/v1/activate | accessible to everybody
GET | /project_name/v1/activate/{id} | accessible to everybody
GET | /project_name/v1/getAllUsers/ | protected by token
GET | /project_name/v1/getUser/{id} | protected by token
POST | /project_name/v1/createUser/ | protected by token
... | /project_name/v1/... | protected by token
我已经厌倦了几种方法。例如:
我尝试过的一切都没有。
是否有一种方法可以使用.permitAll()和.authenticated()在一个公共路径下拥有未经身份验证和受保护的端点?
当前解决方案有效。这是ResourceServerConfiguration类:
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
@Autowired
public ResourceServerConfiguration(final TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
public final void configure(final HttpSecurity http) {
try {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/project_name/activate/v1/**").permitAll()
.antMatchers("/project_name/v1/**").authenticated();
http.servletApi().rolePrefix("");
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
@Override
public void configure(final ResourceServerSecurityConfigurer config) {
config.tokenStore(this.tokenStore);
}
}
答案 0 :(得分:0)
匹配器按照它们出现的顺序进行考虑,如果您想保护BUT 2端点的所有内容,可能需要类似以下内容:
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
@Autowired
public ResourceServerConfiguration(final TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
public final void configure(final HttpSecurity http) {
try {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/project_name/v1/**").authenticated();
.antMatchers("/project_name/v1/activate/**").permitAll()
http.servletApi().rolePrefix("");
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
@Override
public void configure(final ResourceServerSecurityConfigurer config) {
config.tokenStore(this.tokenStore);
}
}
通过这种方式,Spring Security将只覆盖具有匿名访问权限的v1 / activate / **路径,并保持v1 / **中包含的其他路径的安全。
答案 1 :(得分:0)
基于rafura的建议,我试图提出解决方案。扭曲按端点的顺序排列。以下解决方案有效:
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@SuppressWarnings("DesignForExtension")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private final TokenStore tokenStore;
@Autowired
public ResourceServerConfiguration(final TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
@Override
public final void configure(final HttpSecurity http) {
try {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/project_name/v1/activate/**").permitAll()
.antMatchers("/project_name/v1/**").authenticated();
http.servletApi().rolePrefix("");
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}
@Override
public void configure(final ResourceServerSecurityConfigurer config) {
config.tokenStore(this.tokenStore);
}
}
我猜想Spring首先使用适当的路径映射特定端点。然后使用其余的授权级别填充将找到的其余端点。
请注意rafura答案: 倒序不起作用。可能是因为某些路径下的所有内容都获得了授权,并且当Spring找到列出的特定端点时,已经将其标记为必需的授权。如上面的答案所述,反向顺序有效。