Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Security 4.x,动态InvalidSessionUrl_Java_Spring_Security_Spring Security - Fatal编程技术网

Java Spring Security 4.x,动态InvalidSessionUrl

Java Spring Security 4.x,动态InvalidSessionUrl,java,spring,security,spring-security,Java,Spring,Security,Spring Security,我的项目有两个用户角色:[管理员,法庭]和未经验证的匿名用户?用户。管理员具有超级管理员访问权限,即全局访问权限。法院有权访问特定页面。管理员和法庭都经过认证 问题在于,对于这三种人群,需要对会话超时进行不同的处理:管理员和法庭用户需要重新定向到各自的登录页面,未经验证的会话需要根据以前的上下文定向到上下文主页/xyz/home 我在谷歌上搜索过这个话题,但似乎找不到关于这个概念和解决方案的提及。就我从研究中所见,会话管理无效会话url控制着这种行为,但我需要这里的动态值,以便我可以控制登录点

我的项目有两个用户角色:[管理员,法庭]和未经验证的匿名用户?用户。管理员具有超级管理员访问权限,即全局访问权限。法院有权访问特定页面。管理员和法庭都经过认证

问题在于,对于这三种人群,需要对会话超时进行不同的处理:管理员和法庭用户需要重新定向到各自的登录页面,未经验证的会话需要根据以前的上下文定向到上下文主页/xyz/home

我在谷歌上搜索过这个话题,但似乎找不到关于这个概念和解决方案的提及。就我从研究中所见,会话管理无效会话url控制着这种行为,但我需要这里的动态值,以便我可以控制登录点

我的代码:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private MongoUserService mongoUserService;

@Autowired
private LoginAuthenticationEntryPoint loginEntryPoint;

@Autowired
private AuthenticationFailureHandler loginFailureHandler;

@Autowired
private LogoutSuccessHandler logoutSuccessHandler;

@Override
public void configure(WebSecurity web) throws Exception {
    web
        .ignoring()
            .antMatchers("/assets/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .exceptionHandling()
            .authenticationEntryPoint(loginEntryPoint)
            .accessDeniedPage("/403")
        .and()
            .authorizeRequests()
                .antMatchers("/admin/login**").permitAll()
                .antMatchers("/court/login**").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/**/court/**").hasAnyRole("ADMIN","COURT")
            .anyRequest()
                .permitAll()
        .and()
            .formLogin()
                .loginProcessingUrl("/dologin")
                .failureHandler(loginFailureHandler)
                .usernameParameter("username")
                .passwordParameter("password")
        .and()
            .logout()
                .logoutUrl("/dologout")
                .logoutSuccessHandler(logoutSuccessHandler)
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(false)
        .and()
            .sessionManagement()
                .invalidSessionUrl("/")
                .maximumSessions(1)
        ;
}

@Override
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(mongoUserService).passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Component
public class LoginAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    @Autowired
    public LoginAuthenticationEntryPoint() {
        // LoginUrlAuthenticationEntryPoint requires a default
        super("/");
    }

    /**
     * @param request   the request
     * @param response  the response
     * @param exception the exception
     * @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
     */
    @Override
    protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
                                                 AuthenticationException exception) {
        String requestUrl = request.getRequestURI();
        System.out.println("in LoginAuthenticationEntryPoint, requestUrl = " + requestUrl);
        if (requestUrl.indexOf("/admin") != -1) {
            return "/admin/login";
        }
        else if (requestUrl.indexOf("/court") != -1) {
            return "/court/login";
        }
        else {
            return "/admin/login";
        }
    }
}

@Component
public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Autowired
    public AuthenticationFailureHandler() {
        super();
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                    AuthenticationException exception) throws IOException, ServletException {
        setDefaultFailureUrl(getFailureUrl(request));
        super.onAuthenticationFailure(request, response, exception);
    }

    private String getFailureUrl(HttpServletRequest request) {
        String refererUrl = request.getHeader("Referer");
        System.out.println("in AuthenticationFailureHandler, referrerUrl: " + refererUrl);
        if (refererUrl.indexOf("/admin") != -1) {
            return "/admin/login?err=1";
        }
        else if (refererUrl.indexOf("/court") != -1) {
            return "/court/login?err=1";
        }
        else {
            return "/admin/login?err=1";
        }
    }
}

@Component
public class LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {

    @Autowired
    public LogoutSuccessHandler() {
        super();
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, 
                                Authentication authentication) throws IOException, ServletException {
        setDefaultTargetUrl(request.getHeader("Referer"));
        handle(request, response, authentication);
    }
}
}
更新:

当我尝试miplement自定义ConcurrentSessionFilter时,收到一个异常。这是代码,生成的堆栈跟踪如下:

@Bean
public ConcurrentSessionFilter customConcurrentSessionFilter() {
    return new CustomConcurrentSessionFilter();
}

public class CustomConcurrentSessionFilter extends ConcurrentSessionFilter {

    protected String determineExpiredUrl(HttpServletRequest request, SessionInformation info) {
        return "something here";
    }
}
例外情况:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customConcurrentSessionFilter' defined in class path resource [com/cii/config/SecurityConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: SessionRegistry required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4770)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: SessionRegistry required
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.security.web.session.ConcurrentSessionFilter.afterPropertiesSet(ConcurrentSessionFilter.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
    ... 21 more

首先,LogoutSuccessHandler和AuthenticationFailureHandler有缺陷,它们在高并发环境中无法工作。现在,您每次都在重置默认URL。假设用户和管理员同时进入,一个更改会覆盖另一个更改,用户可能会转到管理员页面,反之亦然。但要回答您的问题,请创建一个自定义ConcurrentSessionFilter并重写DetermineeExpireDurl方法。好的,这很有意义。然而,我在实现自定义ConcurrentSessionFilter时遇到了问题;我在初始化时看到异常。过去几天我一直在冒烟,如果这件事简单/直接,我深表歉意。你能给我一个更明确的例子吗?请加上错误。使用自定义类时,您不能使用sessionManagement方法来配置内容,但必须手动完全配置筛选器,并使用addFilterBefore方法将其添加。上面包含代码和错误