我使用的是Spring Boot 1.5.13、Spring Security 4.2.6和Spring Security oAuth2 2.0.15。
我想为我们的Spring Boot应用程序找到一个最佳实践设置,该应用程序提供一组混合内容:一个REST API,一些web页面为开发人员提供一个方便的“登陆页”,上面有一些链接,加上基于Swagger的API文档,这也是web内容。
我的配置允许我使用适当的授权代码流运行应用程序,因此我可以通过浏览器访问所有web内容,并由配置的IdP(在我的例子中是PingFederate)进行身份验证,此外,我可以在浏览器内进行API调用,即直接调用或使用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时,授权代码流会启动并重定向到本地登录endpoint。我想要的是,API调用接受承载令牌进行身份验证,而不创建会话,并且浏览器中的所有web Content/MVC调用都建立会话。
curl -i -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8080/authdemo/api/hello
将@enableResourceServer注释添加到上面的SecurityConfig类中(并在应用程序属性文件中添加security.oauth2.resource.filter-order=3,我可以使curl命令工作,但随后授权代码流中断,我在浏览器中为应用程序中的所有URL获得以下输出:
现在有办法让这个szenario工作得很好吗?如果是,那会是什么样子?还是只在Spring boot+security+oauth2的较晚版本中支持?
使用安全OAuth2启动Spring时的问题--如何使用web登录表单的资源服务器?很相似
我找到了解决方案:它需要多个HttpSecurity配置。通过阅读Matt Raible在https://developer.okta.com/blog/2018/02/13/secure-spring-microservices-with-oauth上写的一篇很棒的文章,我发现了这一点,他向我介绍了requestMatchers(.)的概念。这就是我最终如何实现的:
@Configuration
@EnableResourceServer
@EnableWebSecurity(debug = true)
@EnableOAuth2Sso
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(new RequestHeaderRequestMatcher("Authorization"))
.authorizeRequests().anyRequest().fullyAuthenticated();
}
}
这样,我就可以用浏览器访问服务,从而产生授权代码流。但是访问API(或者实际上是服务的任何部分)会导致对所提供的承载令牌进行验证。
为了说明如何在这种情况下退出/公开一些endpoint,下面是我如何配置执行器endpoint和我自己添加的一个非常简单的“ping”endpoint:
@Configuration
@Order(1)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new OrRequestMatcher(EndpointRequest.to("health", "info"),
new AntPathRequestMatcher("/cfhealth"))).authorizeRequests().anyRequest().permitAll();
}
}
和/cfhealthendpoint的实现:
@Controller
@Slf4j
public class MainController {
@GetMapping(value = "/cfhealth")
@ResponseBody
public String cfhealth() {
return "ok";
}
}
如果这是Spring Security配置的最佳实践方法,或者有更好的方法,我很乐意向其他人学习。在过去的几周里,我在这个主题上花了相当多的时间,要掌握基本的Spring Security概念需要付出相当多的努力。
问题内容: 我正在使用Docker部署我的ASP.NET Core Web API微服务,并且正在寻找将配置注入到每个容器中的选项。在应用程序根目录中使用appsettings.json文件的标准方法并不理想,因为据我所知,这意味着将文件构建到我的docker映像中,这将限制该映像可以在哪个环境中运行。 我想一次构建一个映像,可以在运行时为它们提供配置,并在整个开发过程中进行测试,测试UAT并进入
问题内容: 我想将Java应用程序作为服务运行。不幸的是,我的局限性在于无法使用Java Service Wrapper之 类的工具(它确实是一种出色的工具)。 有什么方法可以在不依赖外部应用程序的情况下将可执行的JAR作为服务运行吗?我当前已安装该服务,但无法启动。这是我遇到的困扰,除了关于JSW的信息之外,我无法在Google上找到其他任何东西。 问题答案: 有Java Service Wra
我有Spring Boot Web应用程序,最初是为内部Tomcat服务器构建的(有效)。然后我采用了该应用程序在Web Logic服务器上运行。我的应用程序编译并部署到服务器没有问题,但当它不服务MVC页面时。每次调用都会抛出404错误。从下面的错误看,它看起来像Spring调度程序servlet存在,但甚至区域设置都没有正确设置。我无法弄清楚这里有什么问题或缺失,但当我创建RestContro
问题内容: 我正在探索Go的深度,并且我一直在尝试编写一个简单的Web应用程序来围绕所有内容。我正在尝试服务React.js应用程序。 下面是Go服务器的代码。我有默认的服务路线,效果很好。我正在努力允许将静态文件提供给该索引文件。尽管我需要静态提供JavaScript / CSS / Media文件,但我允许React App自己进行客户端路由。 例如,我需要能够将文件提供给React应用程序才
我正在尝试将Microsoft Team BOT作为Azure Web应用程序运行-可以在此处找到完整的代码 application.py: 在本地运行时,我可以将端口设置为8000,例如,将ngrok指向localhost,并在我的bot通道注册中指定url,一切正常。我一直在努力让我的代码在Azure中工作,但我就是无法做到这一点。我已将脚本配置为在端口8000上运行,并在应用程序设置中设置参
问题内容: 每当用户断开手机通话时,我都希望显示自定义弹出消息。问题是如何检测应用程序何时未运行。任何线索都将有所帮助。 问题答案: 已经有一段时间了,并且已经有了很多发展。 首先,如何在Flutter中创建服务以使应用程序始终在后台运行有一些答案? 此外,使用Flutter插件和地理围栏(在2018年9月),Flutter / Background流程 基本上将使您指向在后台执行中等/执行Dar