The*_*der 8 java spring stateless-session spring-boot
我已将基本身份验证配置为Spring-Boot应用程序.一切都是Java Config,没有xml.
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Authenticate username -> admin, password -> admin & set role as "ROLE_USER"
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
// All Requests should be Authenticated
.anyRequest().authenticated()
.and()
// Enable Basic Authentication
.httpBasic()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/main", true)
.loginProcessingUrl("/session")
.usernameParameter("Username").passwordParameter("Password")
.and()
.logout().logoutUrl("/logout").permitAll()
.and().csrf().disable();
}
}
Run Code Online (Sandbox Code Playgroud)
它配置为基本身份验证和普通表单登录.当我在Firefox上测试Rest-Client的基本身份验证时,我可以访问安全URL"/ main".但在响应标题中,我得到了Set-Cookie: JSESSIONID=301225C7AE7C74B0892887389996785D;.
我不希望为基本身份验证生成cookie.我想要真正Stateless session的基本身份验证.请注意,我需要为表单登录生成cookie才能工作,因此禁用cookie不是一种选择.我知道create-session="stateless"在xml配置中,但有没有办法在Java配置中做同样的事情,以便基本身份验证是无状态的,而表单身份验证是状态的...?
sha*_*zin 11
I know about the create-session="stateless" in xml configuration, but is there any way to do the same in Java config so that Basic Authentication is Stateless and Form-Authentication is Statefull..?
Run Code Online (Sandbox Code Playgroud)
您可以执行以下操作.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Run Code Online (Sandbox Code Playgroud)
对于您的问题,可以使用自定义Java Config.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Inject
UserDetailsService userService;
@Bean
public AuthenticationManager authenticationManager() throws Exception {
AuthenticationManager authenticationManager = new ProviderManager(
Arrays.asList(authenticationProvider()));
return authenticationManager;
}
@Bean
public AuthenticationProvider authenticationProvider() throws Exception {
CustomAuthenticationProvider authenticationProvider = new CustomAuthenticationProvider();
authenticationProvider.setUserDetailsService(userService);
authenticationProvider.setSaltSource(saltSource());
authenticationProvider.setPasswordEncoder(passwordEncoder());
authenticationProvider.afterPropertiesSet();
return authenticationProvider;
}
@Bean
public SaltSource saltSource() throws Exception {
ReflectionSaltSource saltSource = new ReflectionSaltSource();
saltSource.setUserPropertyToUse("salt");
saltSource.afterPropertiesSet();
return saltSource;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new Md5PasswordEncoder();
}
@Bean
public FilterChainProxy springSecurityFilterChain()
throws ServletException, Exception {
List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>();
securityFilterChains.add(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/login**")));
securityFilterChains.add(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/resources/**")));
securityFilterChains.add(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/api/**"),
securityContextPersistenceFilterASCFalse(),
basicAuthenticationFilter(), exceptionTranslationFilter(),
filterSecurityInterceptor()));
securityFilterChains.add(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/**"),
securityContextPersistenceFilterASCTrue(), logoutFilter(),
usernamePasswordAuthenticationFilter(),
exceptionTranslationFilter(), filterSecurityInterceptor()));
return new FilterChainProxy(securityFilterChains);
}
@Bean
public SecurityContextPersistenceFilter securityContextPersistenceFilterASCTrue() {
return new SecurityContextPersistenceFilter(
new HttpSessionSecurityContextRepository());
}
@Bean
public SecurityContextPersistenceFilter securityContextPersistenceFilterASCFalse() {
HttpSessionSecurityContextRepository httpSessionSecurityContextRepository = new HttpSessionSecurityContextRepository();
httpSessionSecurityContextRepository.setAllowSessionCreation(false);
return new SecurityContextPersistenceFilter(
httpSessionSecurityContextRepository);
}
@Bean
public ExceptionTranslationFilter exceptionTranslationFilter() {
ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(
new LoginUrlAuthenticationEntryPoint("/login"));
AccessDeniedHandlerImpl accessDeniedHandlerImpl = new AccessDeniedHandlerImpl();
accessDeniedHandlerImpl.setErrorPage("/exception");
exceptionTranslationFilter
.setAccessDeniedHandler(accessDeniedHandlerImpl);
exceptionTranslationFilter.afterPropertiesSet();
return exceptionTranslationFilter;
}
@Bean
public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter()
throws Exception {
UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter = new UsernamePasswordAuthenticationFilter();
usernamePasswordAuthenticationFilter
.setAuthenticationManager(authenticationManager());
usernamePasswordAuthenticationFilter.setAllowSessionCreation(true);
SimpleUrlAuthenticationSuccessHandler successHandler = new SimpleUrlAuthenticationSuccessHandler(
"/index");
successHandler.setAlwaysUseDefaultTargetUrl(true);
usernamePasswordAuthenticationFilter
.setAuthenticationSuccessHandler(successHandler);
usernamePasswordAuthenticationFilter
.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(
"/login?error=true"));
usernamePasswordAuthenticationFilter
.setAuthenticationDetailsSource(new CustomWebAuthenticationDetailsSource());
usernamePasswordAuthenticationFilter.afterPropertiesSet();
return usernamePasswordAuthenticationFilter;
}
@Bean
public FilterSecurityInterceptor filterSecurityInterceptor()
throws Exception {
FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
filterSecurityInterceptor
.setAuthenticationManager(authenticationManager());
filterSecurityInterceptor
.setAccessDecisionManager(accessDecisionManager());
filterSecurityInterceptor.setRunAsManager(runAsManager());
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
List<ConfigAttribute> configs = new ArrayList<ConfigAttribute>();
configs.add(new org.springframework.security.access.SecurityConfig(
"isAuthenticated()"));
requestMap.put(new AntPathRequestMatcher("/**"), configs);
FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource = new ExpressionBasedFilterInvocationSecurityMetadataSource(
requestMap, new DefaultWebSecurityExpressionHandler());
filterSecurityInterceptor
.setSecurityMetadataSource(filterInvocationSecurityMetadataSource);
filterSecurityInterceptor.afterPropertiesSet();
return filterSecurityInterceptor;
}
public AffirmativeBased accessDecisionManager() throws Exception {
List<AccessDecisionVoter> voters = new ArrayList<AccessDecisionVoter>();
voters.add(new WebExpressionVoter());
voters.add(new RoleVoter());
AffirmativeBased affirmativeBased = new AffirmativeBased(voters);
affirmativeBased.setAllowIfAllAbstainDecisions(false);
affirmativeBased.afterPropertiesSet();
return affirmativeBased;
}
@Bean
public RunAsManager runAsManager() throws Exception {
RunAsManagerImpl runAsManager = new RunAsManagerImpl();
runAsManager.setKey("V_RUN_AS");
runAsManager.afterPropertiesSet();
return runAsManager;
}
@Bean
public LogoutFilter logoutFilter() throws ServletException {
List<LogoutHandler> handlers = new ArrayList<LogoutHandler>();
handlers.add(new CookieClearingLogoutHandler("JSESSIONID"));
handlers.add(new SecurityContextLogoutHandler());
LogoutFilter logoutFilter = new LogoutFilter("/login",
handlers.toArray(new LogoutHandler[] {}));
logoutFilter.afterPropertiesSet();
return logoutFilter;
}
@Bean
public RequestContextFilter requestContextFilter() {
return new RequestContextFilter();
}
@Bean
public BasicAuthenticationFilter basicAuthenticationFilter()
throws Exception {
BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
basicAuthenticationEntryPoint.setRealmName("V_REALM");
basicAuthenticationEntryPoint.afterPropertiesSet();
BasicAuthenticationFilter basicAuthenticationFilter = new BasicAuthenticationFilter(
authenticationManager(), basicAuthenticationEntryPoint);
basicAuthenticationFilter
.setAuthenticationDetailsSource(new CustomWebAuthenticationDetailsSource());
basicAuthenticationFilter.afterPropertiesSet();
return basicAuthenticationFilter;
}
}
Run Code Online (Sandbox Code Playgroud)
此配置创建两种不同的身份验证机制
对于任何以/api/*它开头的请求,将使用a basicAuthenticationFilter和securityContextPersistenceFilterASCFalseSession Creation False.
对于任何以/*它开头的请求,将使用a usernamePasswordAuthenticationFilter和securityContextPersistenceFilterASCTrueSession Creation True.
你可以利用它并改变它来迎合你的问题.
对于遇到此问题的其他人,这里还有其他需要检查的内容。
我在 Spring Boot 中遇到了同样的问题,甚至
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
Run Code Online (Sandbox Code Playgroud)
我仍然看到 JSESSIONID cookie 被设置。就我而言(使用 JWT),缺少的部分似乎是在HttpSessionSecurityContextRepository对象上设置 setAllowSessionCreation,如下所示:
public class StatelessAuthenticationFilter extends GenericFilterBean {
private final MyTokenAuthService authenticationService;
private SecurityContextRepository repository = new HttpSessionSecurityContextRepository();
protected final Logger logger = LoggerFactory.getLogger(getClass().getName());
public StatelessAuthenticationFilter(MyTokenAuthService authenticationService) {
this.authenticationService = authenticationService;
((HttpSessionSecurityContextRepository) repository).setAllowSessionCreation(false);
}
}
Run Code Online (Sandbox Code Playgroud)
向我指出这一点的是以下几行HttpSessionSecurityContextRepository:
private boolean allowSessionCreation = true;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10239 次 |
| 最近记录: |