[英]Combining Oauth2 with formlogin and actuator security in Spring Boot
I am using Spring Boot 1.5.9 and have an application that has an API that uses OAuth2 client credentials, with formlogin for a CMS that uses Thymeleaf in the same Spring Boot application. 我正在使用Spring Boot 1.5.9,并且有一个应用程序具有使用OAuth2客户端凭据的API,而formlogin用于在同一个Spring Boot应用程序中使用Thymeleaf的CMS。
For this to work, I have the following bean to configure the form login: 为此,我有以下bean来配置表单登录:
@Configuration
public class WebSecurityGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// api security is handled elsewhere (See OAuth2ServerConfiguration)
.antMatchers("/api/**", "/oauth/**", "/management/**")
.permitAll()
// end api security
.anyRequest().hasRole(UserRole.ADMIN.name())
.and()
.formLogin().loginPage("/login")
.permitAll()
.and()
.logout().permitAll();
}
}
So for the form login part, I declare everything related to API, Oauth and /management (the custom context-path I have set in application.properties
for the actuator endpoints): 因此,对于表单登录部分,我声明了与API,Oauth和/ management相关的所有内容(我在application.properties
为执行器端点设置的自定义上下文路径):
management.context-path=/management
management.security.roles=ADMIN
For Oauth2, I have this: 对于Oauth2,我有这个:
@Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "my-app-service";
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/api/**")
.permitAll()
.and()
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.authorizeRequests()
.antMatchers("/management/health", "/management/info").permitAll()
.antMatchers("/management/**").hasRole(UserRole.ADMIN.name())
.anyRequest().authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private TokenStore tokenStore;
@Autowired
private SecurityConfiguration securityConfiguration;
// NOTE: If you set a new validity, you need to clear the 'oauth_access_token' table
// in the database. Only new tokens get the new validity.
@Value("${myapp.security.oauth.access-token-validity-seconds:43200}") // 12 hours by default
private int accessTokenValiditySeconds;
@Value("${myapp.security.oauth.refresh-token-validity-seconds:2592000}") // 30 days by default
private int refreshTokenValiditySeconds;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.passwordEncoder(passwordEncoder);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(securityConfiguration.getMobileAppClientId())
.authorizedGrantTypes("password", "refresh_token")
.scopes("mobile_app")
.resourceIds(RESOURCE_ID)
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.secret(passwordEncoder.encode(securityConfiguration.getMobileAppClientSecret()));
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).
authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
}
I want the following behaviour: 我想要以下行为:
ADMIN
by using an Oauth2 access token, all actuator endpoints must be accessible 如果用户使用Oauth2访问令牌具有角色ADMIN
,则必须可以访问所有执行器端点 ADMIN
role, only /health
and /info
should be accessible (If ADMIN
, /health
should show extra info like it is by default) 如果用户没有此ADMIN
角色,则只能访问/health
和/info
(如果ADMIN
, /health
应显示默认情况下的额外信息) The current behaviour: 目前的行为:
The info and health endpoints can be viewed by everybody, but as ADMIN, you don't get extra info. 每个人都可以查看信息和健康端点,但作为ADMIN,您无法获得额外信息。 For the other endpoints, I get a 401 if I try with an access token of an ADMIN user with: 对于其他端点,如果我尝试使用ADMIN用户的访问令牌,则会获得401:
{
"timestamp": "2018-01-30T13:45:26.625+0000",
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource.",
"path": "/management/beans"
}
If I set management.security.enabled=false
then the ADMIN user has access, but all non-ADMIN users also have access. 如果我设置management.security.enabled=false
则ADMIN用户具有访问权限,但所有非ADMIN用户也具有访问权限。
What should I change to get the wanted behaviour? 我应该改变什么来获得想要的行为?
I managed to make it work with the following in the configure
method of ResourceServerConfiguration
: 我设法使它在ResourceServerConfiguration
的configure
方法中使用以下内容:
http
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/api/**")
.permitAll()
.and()
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.and()
.requestMatchers()
.antMatchers("/management/**")
.and()
.authorizeRequests()
.antMatchers("/management/health", "/management/info").permitAll()
.antMatchers("/management/**").hasRole(UserRole.ADMIN.name())
.anyRequest()
.authenticated()
Using multiple antMatchers
directly on the http
object does not work, you need to first use requestMatchers
直接在http
对象上使用多个antMatchers
不起作用,您需要首先使用requestMatchers
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.