【发布时间】:2018-10-23 04:07:29
【问题描述】:
我正在使用 Spring Boot 1.5.13 以及 Spring Security 4.2.6 和 Spring Security oAuth2 2.0.15。
我想为我们的 Spring Boot 应用程序找到一个最佳实践设置,这些应用程序提供混合的内容集:一个 REST API,以及一些为开发人员提供便利的“登陆页面”的网页,上面有一些链接,还有 Swagger基于 API 的文档,也是网页内容。
我的配置允许我使用适当的授权代码流运行应用程序,因此我可以通过浏览器访问所有 Web 内容并通过配置的 IdP(在我的情况下为 PingFederate)进行身份验证,另外我可以从在浏览器中,即直接或使用 REST 客户端,例如使用 RESTClient。
这是我的安全配置:
@Slf4j
@Configuration
@EnableWebSecurity
@EnableOAuth2Sso // this annotation must stay here!
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login**", "/webjars/**", "/css/**").permitAll()
.antMatchers("/cfhealth").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/protected", "/api/**").authenticated();
}
@Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
}
以及 oAuth2 配置:
@Configuration
@Slf4j
public class OAuth2Config extends ResourceServerConfigurerAdapter {
@Value("${pingfederate.pk-uri}")
String pingFederatePublicKeyUri;
@Autowired
PingFederateKeyUtils pingFederateKeyUtils;
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
String certificate = pingFederateKeyUtils.getKeyFromServer(pingFederatePublicKeyUri);
String publicKey = pingFederateKeyUtils.extractPublicKey(certificate);
converter.setVerifier(pingFederateKeyUtils.createSignatureVerifier(publicKey));
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}
但是当我想以编程方式/在浏览器外部调用 REST API 时,标题中带有不记名令牌,例如使用 curl,授权代码流启动并重定向到本地登录端点。我想要的是 API 调用接受承载令牌进行身份验证,而不创建会话,并且浏览器中的所有 Web 内容/mvc 调用都建立会话。
curl -i -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8080/authdemo/api/hello
在上面的SecurityConfig类中添加@EnableResourceServer注解(并在应用程序属性文件中添加security.oauth2.resource.filter-order=3,我可以使curl命令工作,但随后授权代码流被破坏,对于我的应用程序中的所有 URL,我在浏览器中得到以下输出:
<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>
现在有没有办法让这个场景很好地工作?如果是,那会是什么样子?还是只有更高版本的Spring Boot+Security+oAuth2才支持?
Spring Boot with Security OAuth2 - how to use resource server with web login form?的问题很相似
【问题讨论】:
标签: spring-boot spring-security spring-security-oauth2 pingfederate openid-connect