Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.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 x509身份验证失败时重定向循环_Java_Spring_Spring Boot_Spring Security_X509 - Fatal编程技术网

Java x509身份验证失败时重定向循环

Java x509身份验证失败时重定向循环,java,spring,spring-boot,spring-security,x509,Java,Spring,Spring Boot,Spring Security,X509,我有一个带有x509身份验证的spring启动应用程序。我的问题是,当身份验证失败时,我得到的是重定向循环,而不是错误屏幕 当身份验证失败时,我从arhivx509userdetailssservice.java中的方法抛出UsernameNotFoundException loadUserDetails @Service("x509UserDetailsService") public class ArhivX509UserDetailsService implements A

我有一个带有x509身份验证的spring启动应用程序。我的问题是,当身份验证失败时,我得到的是重定向循环,而不是错误屏幕

当身份验证失败时,我从arhivx509userdetailssservice.java中的方法抛出UsernameNotFoundException loadUserDetails

@Service("x509UserDetailsService")
public class ArhivX509UserDetailsService
        implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
    @Autowired
    private IUserProfileService iUserProfileService;

    @Autowired
    private ICheckCertificateService iCheckCertService;


    @Override
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken pToken) throws UsernameNotFoundException {
        X509Certificate tCertificate = (X509Certificate) pToken.getCredentials();
        String tSubjectDN = tCertificate.getSubjectDN().toString().toUpperCase();
        ProfilKorisnika tProfilKorisnika = iUserProfileService.getUserProfile(tSubjectDN);

        if (tProfilKorisnika == null) {
            throw new UsernameNotFoundException("Pogreška kod prijave korisnika.");
        }

        return tProfilKorisnika;

    }
}
我的代码如下:

SecurityConfiguration.java

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
@Qualifier("x509UserDetailsService")
private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> iX509UserDetailsService;

@Override
protected void configure(HttpSecurity pHttp) throws Exception {
    //@formatter:off
    pHttp
        .authorizeRequests()
            .antMatchers("/webjars/**").permitAll()
            .antMatchers("/error").permitAll()
            .antMatchers("/error401").permitAll()
            .anyRequest().authenticated()
            .and()
        .x509()
            .subjectPrincipalRegex("(.*)")
            .authenticationUserDetailsService(iX509UserDetailsService)
            .and()
            .addFilterAfter(new X509ErrorCheckerFilter(),  X509AuthenticationFilter.class)
            .addFilterBefore(new LoggerMDCFilter(),  X509ErrorCheckerFilter.class)
        .exceptionHandling()
            .authenticationEntryPoint(unauthorizedEntryPoint())
            .accessDeniedPage(AppUrls.ERROR_401)
            .and()
        .requiresChannel()
            .anyRequest()
            .requiresSecure()
            .and()
        .sessionManagement()
            .maximumSessions(1)
            .and()
            .and()
        .logout()
            .invalidateHttpSession(true)
            .deleteCookies("SESSION", "JSESSIONID")
            .logoutSuccessUrl("http://www.google.com")
            .permitAll();
    //@formatter:on
}

@Bean
public AuthenticationEntryPoint unauthorizedEntryPoint() {
    return new AuthenticationEntryPoint() {
        @Override
        public void commence(HttpServletRequest pRequest, HttpServletResponse pResponse,
                AuthenticationException pAuthException) throws IOException, ServletException {
            pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    };
}
}
如果您需要更多详细信息,请询问。

将permitAll()应用于/error401意味着当安全筛选器链完成执行时,无论当前SecurityContext中是否存在身份验证,请求都将正常处理

X509ErrorCheckerFilter正在将所有未经验证的请求从filterchain内转发到/error401,因此永远不会应用permitAll()。相反,转发的请求再次通过filterchain并使身份验证失败,从而导致循环重定向

要解决这个问题,您有几个选项。以下是几点:

1.禁用错误终结点的安全性 您可以在SecurityConfiguration类中禁用端点的安全性。这是最简单的选择

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/error*");
}
2.实现接口 对于实现ErrorController的控制器中包含的请求映射,将不会调用安全筛选器链

请参见Spring自己的参考()

第二个选项更可取,因为它消除了过滤器中重定向的任何要求。相反,它让Spring Security通过身份验证过程完成路由请求的繁重工作。当安全过滤器链完成处理时,只要会话的SecurityContext中没有经过身份验证的内容,spring security将返回401并返回ErrorController指定的错误页面

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