java - 为多个入口点配置spring security?
问题描述
我正在尝试为我的应用程序设置弹簧安全性。它有多个入口点,如下:
1. /odk/**
- 所有前缀为 /odk/ 的路由都应使用 Digest Auth 进行身份验证并相应地响应
2. /odkx/**
- 所有前缀为 /odkx/ 的路由也应该使用 Digest Auth 进行身份验证并相应地响应
3. /api/**
- 前缀为 /api/ 的所有路由都应使用 JWT 身份验证进行身份验证
4. 所有其他路由
- 与上述任何不匹配的所有路由都应使用 spring 的登录表单身份验证进行身份验证安全。
我编写的代码还为每个入口点添加了@order,以便相应地执行。我的问题是所有过滤器都被执行,而请求应该只由相关入口点处理。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
web.ignoring().antMatchers("/css/**");
web.ignoring().antMatchers("/jsp/**");
}
@Configuration
@Order(1)
public static class DigestAuthSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomDigestUserService customDigestUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.antMatcher("/odk/**")
.authorizeRequests().antMatchers("/odk/**")
.fullyAuthenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(digestAuthFilter())BasicAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(digestEntryPoint());
}
DigestAuthenticationFilter digestAuthFilter() throws Exception {
DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
digestAuthenticationFilter.setUserDetailsService(customDigestUserService);
digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPoint());
digestAuthenticationFilter.setPasswordAlreadyEncoded(false);
return digestAuthenticationFilter;
}
DigestAuthenticationEntryPoint digestEntryPoint() {
DigestAuthenticationEntryPoint bauth = new DigestAuthenticationEntryPoint();
bauth.setRealmName("Digest ASIMS");
bauth.setKey("MySecureKey");
return bauth;
}
}
@Configuration
@Order(2)
public static class DigestAuthSecurityConfigurationODKX extends WebSecurityConfigurerAdapter {
@Autowired
private CustomDigestUserService customDigestUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.antMatcher("/odkx/**")
.authorizeRequests().antMatchers("/odkx/**")
.fullyAuthenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(digestAuthFilterODKX())BasicAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(digestEntryPointODKX());
}
DigestAuthenticationFilter digestAuthFilterODKX() throws Exception {
DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
digestAuthenticationFilter.setUserDetailsService(customDigestUserService);
digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPointODKX());
digestAuthenticationFilter.setPasswordAlreadyEncoded(false);
return digestAuthenticationFilter;
}
DigestAuthenticationEntryPoint digestEntryPointODKX() {
DigestAuthenticationEntryPoint bauth = new DigestAuthenticationEntryPoint();
bauth.setRealmName("Digest ASIMS");
bauth.setKey("MySecureKey");
return bauth;
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(customDigestUserService);
}
}
@Configuration
@Order(3)
public static class JwtAuthSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserService customUserService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
@Autowired
public JwtAuthenticationFilter jwtAuthenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(customUserService).passwordEncoder(jwtPasswordEncoder());
}
public BCryptPasswordEncoder jwtPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Configuration
@Order(4)
public static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserService customUserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login");
}
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(customUserService);
auth.setPasswordEncoder(passwordEncoder());
auth.setHideUserNotFoundExceptions(false);
return auth;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
}
}
这是日志
2019-08-12 20:40:05 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 6 of 12 in additional filter chain; firing Filter: 'DigestAuthenticationFilter'
2019-08-12 20:40:05 DEBUG org.springframework.security.web.authentication.www.DigestAuthenticationFilter - Digest Authorization header received from user agent: Digest username="admin", realm="Digest ASIMS", nonce="MTU2NTYyNjUwNTI1MTplNjFjYjVhODU2ODU3ZmFiNTdmMzI2NGMwZmYyOGE1MQ==", uri="/odk/formList", algorithm="MD5", qop=auth, nc=00000001, cnonce="QLgL7tFi", response="b58667867ba602024aa1c64ffd0c24a5"
2019-08-12 20:40:05 DEBUG org.springframework.security.web.authentication.www.DigestAuthenticationFilter - Extracted username: 'admin'; realm: 'Digest ASIMS'; nonce: 'MTU2NTYyNjUwNTI1MTplNjFjYjVhODU2ODU3ZmFiNTdmMzI2NGMwZmYyOGE1MQ=='; uri: '/odk/formList'; response: 'b58667867ba602024aa1c64ffd0c24a5'
Entry to CustomDigestUserServiceImpl: admin
2019-08-12 20:40:05 DEBUG org.hibernate.SQL -
2019-08-12 20:40:13 DEBUG org.springframework.security.web.authentication.www.DigestAuthenticationFilter - Authentication success for user: 'admin' with response: 'b58667867ba602024aa1c64ffd0c24a5'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.authentication.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@ac07c509: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: VIEW,EDIT,DELETE; Credentials: [PROTECTED]; Authenticated: false; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy - Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@2a54a6c3
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.FilterChainProxy - /odk/formList at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/odk/formList'; against '/odk/**'
2019-08-12 20:40:31 DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /odk/formList; Attributes: [fullyAuthenticated]
2019-08-12 20:40:31 DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
Entry to CustomUserService: admin
2019-08-12 20:40:31 DEBUG org.hibernate.SQL -
2019-08-12 20:40:31 DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider - Authentication failed: password does not match stored value
2019-08-12 20:40:31 DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.BadCredentialsException: Bad credentials
解决方案
推荐阅读
- r - 如何根据不同列的值从一列中选择值?
- sqlite - Tcl StarKit 与 SQLite 数据库作为程序?
- xml - xmlMapper 找不到字符串创建者
- apache-flink - 每个保存点结束后内存都会增加一点
- android - 构建失败 D:\My Folder\Android\Android SDK\tools\ant\build.xml:538: 无法解析项目目标“Google Inc.:Google APIs:13”
- python - 如何按 id 分组以使所有数据集成为一个数据集
- javascript - 即使数据确认存在于前一行,也会出现此错误!我错过了吗?TypeError:无法读取未定义的属性“包含”
- excel - Excel VBA从另一个excel中获取数据,源数据的路径作为变量
- rust - Rust Diesel sql_query 带有返回的插入示例
- python - 一旦对消息做出反应,如何让机器人向用户发送消息?