Spring Boot 和 Spring Cloud Security OAUTH 2 SSO 在最新版本中失败 [英] Spring Boot and Spring Cloud Security OAUTH 2 SSO Failing with latest releases
问题描述
我正在尝试将带有 OAuth 的 Spring Boot 和 Spring Cloud Security 示例从 Spring Boot 1.4.1 + Brixton.RELEASE 升级到 Spring Boot 1.5.3+ Dalston.RELEASE.然而,经过长时间的努力,没有取得任何成功.
I am trying to upgrade a sample Spring Boot and Spring Cloud Security with OAuth from Spring Boot 1.4.1 + Brixton.RELEASE to Spring Boot 1.5.3+ Dalston.RELEASE. However, it has been a long hard try without any success.
似乎由于某种原因资源服务器安全过滤器链没有被触发.因此,对/me"或/user"的调用由默认安全过滤器链处理.我在想这是否是订单问题.但是尝试如下显式设置安全过滤器链的顺序
It seems for some reason the resource server security filter chain is not getting fired. As a result the call to "/me" or "/user" is being handled by default security filter chain. I am thinking if this is a problem with order. But tried to explicitly set the order of the security filter chains as follows
- 身份验证服务器 6
- 网络默认 5
- 资源服务器 3(硬编码 ??)
由于默认过滤器链正在处理请求,它总是转到登录页面,生成 HTML 并且 SSO 客户端(服务器端 thymeleaf Web UI)失败.
Since the default filter chain is handling the request, it is always going to the login page, which generates HTML and the SSO client (server side thymeleaf web UI) fails.
源代码如下
授权服务器
@SpringBootApplication
public class MyAuthServerApplication {
public static void main(String[] args) {
SpringApplication.run(MyAuthServerApplication.class, args);
}
}
然后是授权服务器配置
@Configuration
@EnableAuthorizationServer
@Order(6)
public class AuthorizationServerConfigurer extends A
uthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws
Exception {
clients.inMemory()
.withClient("myauthserver")
.secret("verysecretpassword")
.redirectUris("http://localhost:8080/")
.authorizedGrantTypes("authorization_code", "refresh_token")
.scopes("myscope")
.autoApprove(true);
}
}
然后是资源服务器类
@Configuration
@EnableResourceServer
public class ResourceServerConfigurer extends
ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user")
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
Web MVC 配置
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("login").setViewName("login");
}
}
默认 spring 安全配置
The default spring security configuration
@Configuration
@EnableWebSecurity
@Order(9)
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and().csrf()
.and().formLogin().loginPage("/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("admin").roles("USER", "ADMIN");
}
}
资源控制器
@RestController
public class ResourceController {
@RequestMapping(value = { "/user" }, produces = "application/json")
public Map<String, Object> user(OAuth2Authentication user) {
Map<String, Object> userDetails = new HashMap<>();
userDetails.put("user", user.getUserAuthentication().getPrincipal());
userDetails.put("authorities",
AuthorityUtils.
authorityListToSet(user.getUserAuthentication().getAuthorities()));
return userDetails;
}
}
最后的配置 - 认证服务器的 application.yml
Finally the configuration - application.yml for the auth server
server:
port: 9090
contextPath: /auth
logging:
level:
org.springframework: INFO
org.springframework.security: DEBUG
此处未显示 login.html Thymeleaf 模板.
The login.html Thymeleaf template is not shown here.
OAUTH 2 SSO 客户端网络应用
@SpringBootApplication
public class MyWebsiteApplication {
public static void main(String[] args) {
SpringApplication.run(MyWebsiteApplication.class, args);
}
}
网络安全配置
@Configuration
@EnableOAuth2Sso
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll() // Allow navigating to index
page,
.anyRequest().authenticated(); // but secure all the other URLs
}
}
网络控制器
@控制器公共类 MyWebsiteController {
@Controller public class MyWebsiteController {
/**
* Default index page to verify that our application works.
*/
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return "Hello world!";
}
/**
* Return a ModelAndView which will cause the
'src/main/resources/templates/time.html' template to be rendered,
* with the current time.
*/
@RequestMapping("/time")
public ModelAndView time() {
ModelAndView mav = new ModelAndView("time");
mav.addObject("currentTime", getCurrentTime());
return mav;
}
private String getCurrentTime() {
return LocalTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
}
}
应用程序配置 - 客户端 Web 应用程序的 application.yml
The application configuration - application.yml for the client web app
server:
port: 8080
contextPath: /
security:
oauth2:
client:
accessTokenUri: http://localhost:9090/auth/oauth/token
userAuthorizationUri: http://localhost:9090/auth/oauth/authorize
clientId: myauthserver
clientSecret: verysecretpassword
resource:
userInfoUri: http://localhost:9090/auth/user
此处未显示 time.html 页面的 Thymeleaf 模板.
The Thymeleaf template for the time.html page is not shown here.
一定有一些细微的小配置错误或一些我不知道的错误.非常感谢任何帮助或想法.
There must be some subtle little configuration thats wrong or some bug I do not know. Any help or ideas highly appreciated.
推荐答案
解决方案
猜对了,安全过滤器链的顺序已经改变.这是
的链接Spring 1.5.x 发行说明
Guess was right the ordering of the security filter chain got was changed. Here is the link to the
Spring 1.5.x release note
修改后的代码在这里,稍后会上传到Github.身份验证服务器配置上的所有更改.
Modified code is here and will upload it to Github later. All changes on the auth server configuration.
Spring 安全配置 - 删除 @Order 注释.
The Spring security configuration - remove the @Order annotation.
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and().csrf()
.and().formLogin().loginPage("/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("admin").roles("USER", "ADMIN");
}
}
然后将application.yml改成如下
Then change the application.yml as follows
server:
port: 9090
contextPath: /auth
logging:
level:
org.springframework: INFO
org.springframework.security: DEBUG
security:
oauth2:
resource:
filter-order : 3
就是这样,在身份验证服务器上进行身份验证后,时间会显示在客户端应用程序/time url 上.
That's it then the time is displayed on the client application /time url after authentication on the auth server.
这篇关于Spring Boot 和 Spring Cloud Security OAUTH 2 SSO 在最新版本中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!