我正在使用Spring Boot 1.5.9,并且有一个应用程序具有使用OAuth2客户端凭据的API,而formlogin用于在同一个Spring Boot应用程序中使用Thymeleaf的CMS。
为此,我有以下bean来配置表单login:
@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();
}
}
因此,对于表单登录部分,我声明了与API,Oauth和/ management相关的所有内容(我在application.properties
中为执行器端点设置的自定义上下文路径):
management.context-path=/management
management.security.roles=ADMIN
对于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);
}
}
}
我想要以下行为:
ADMIN
,则必须可以访问所有执行器端点ADMIN
个角色,则只能访问/health
和/info
(如果ADMIN
,则/health
应显示额外信息,例如{
"timestamp": "2018-01-30T13:45:26.625+0000",
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource.",
"path": "/management/beans"
}
默认情况下)目前的行为:
每个人都可以查看信息和健康端点,但作为ADMIN,您无法获得额外信息。对于其他端点,如果我尝试使用ADMIN用户的访问令牌,则会得到401:
management.security.enabled=false
如果我设置{{1}},则ADMIN用户具有访问权限,但所有非ADMIN用户也有权访问。
我应该改变什么来获得想要的行为?
答案 0 :(得分:2)
我设法在configure
的{{1}}方法中使用以下内容:
ResourceServerConfiguration
直接在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()
对象上使用多个antMatchers
不起作用,您需要先使用http