我正在尝试为两个端点/api
和/admin
配置安全性。
对于/api
,我想使用基于jwt令牌的无状态机制进行保护,而对于/admin
,我想使用基于表单的登录。
在Spring security oauth2 and form login configuration上已经找到其他人之后,我尝试配置它。
会根据我为配置设置的/admin
来使我的/api
受保护或@Order
受保护。
一些关于整数值的排序是如何无效的。必须使用org.springframework.core.Ordered
进行设置,然后只有资源服务器配置获得优先级
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Configuration
@EnableWebSecurity
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(ApiWebSecurityConfigurationAdapter.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("\n---------\n m here ApiWebSecurityConfigurationAdapter\n---------\n");
http.authorizeRequests().antMatchers("/api/**").hasRole("USER").and().formLogin();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Configuration
@Order(1)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(FormLoginWebSecurityConfigurerAdapter.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("\n---------\n m here FormLoginWebSecurityConfigurerAdapter\n---------\n");
http.csrf().disable().authorizeRequests().antMatchers("/admin/**")
.hasAnyAuthority("admin", "ADMIN_USER").and().formLogin().permitAll().and().logout().permitAll();
}
}
@Configuration
@EnableResourceServer
@Order(2)
public class CustomResourceServerConfigurerAdapter extends ResourceServerConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(CustomResourceServerConfigurerAdapter.class);
@Autowired
private JdbcTemplate jdbcTemplate;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(jdbcTemplate.getDataSource());
}
@Bean
@Primary
//Making this primary to avoid any accidental duplication with another token service instance of the same name
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices());
}
@Override
public void configure(HttpSecurity http) throws Exception {
logger.info("\n---------\n m here CustomResourceServerConfigurerAdapter\n---------\n");
http.authorizeRequests()
.and()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().httpBasic()
.and()
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated();
}
}
}
和我的OAuth2Configuration
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private TokenStore tokenStore;
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
return new JwtAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore)
.reuseRefreshTokens(false)
.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter())
.userDetailsService(userDetailsService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(jdbcTemplate.getDataSource());
}
}
我希望同时保护两个端点,即使用jwt令牌保护/api
并使用基于表单的登录保护/admin
。我不想为Rest API和UI实施2个不同的项目
感谢@dur睁大了眼睛
我能够使用
保护我的其余api@Override
public void configure(HttpSecurity http) throws Exception {
logger.info("\n---------\n m here CustomResourceServerConfigurerAdapter\n---------\n");
http
.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/**" ).authenticated();
}
但是我无法保护自己的/admin
,除非使用httpBasic
如果有人可以告诉我如何配置表单登录名,将非常有帮助
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("\n---------\n m here FormLoginWebSecurityConfigurerAdapter\n---------\n");
http
.antMatcher("/admin/**")
.authorizeRequests()
.anyRequest().hasAnyAuthority("ADMIN_USER")
.and()
.httpBasic();
}
我尝试过
http.antMatcher("/admin/**").authorizeRequests()
.antMatchers("/admin/**").hasAnyAuthority("ADMIN_USER")
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
但这没用
最终明白了
http
.antMatcher("/admin/**")
.authorizeRequests()
.anyRequest().hasAnyAuthority("ADMIN_USER")
.and()
.formLogin()
.loginPage("/admin/login")
.permitAll()
.and()
.logout()
.logoutUrl("/admin/logout")
.invalidateHttpSession(true)
.permitAll();
http.csrf().disable();