Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.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为基本身份验证配置多种身份验证类型&;JWT_Java_Spring Boot_Spring Security_Basic Authentication_Jwt Auth - Fatal编程技术网

Java 使用spring security为基本身份验证配置多种身份验证类型&;JWT

Java 使用spring security为基本身份验证配置多种身份验证类型&;JWT,java,spring-boot,spring-security,basic-authentication,jwt-auth,Java,Spring Boot,Spring Security,Basic Authentication,Jwt Auth,我有一个API,需要以两种不同的方式进行保护: 1) 对除1以外的所有请求URL使用JWT,该URL需要使用基本身份验证进行保护 2) 一个url的基本身份验证 我已经为JWT和Basic Auth设置了安全配置。我的问题是,当我向基本的经过身份验证的URL发出请求时 使用有效的用户名和密码,它成功地对我进行身份验证,并将数据存储在cassandra中 然后,我希望必须通过/api/login为所有其他请求URL生成一个令牌,并将其添加到Authorization:Bearer{token}头中

我有一个API,需要以两种不同的方式进行保护:

1) 对除1以外的所有请求URL使用JWT,该URL需要使用基本身份验证进行保护

2) 一个url的基本身份验证

我已经为JWT和Basic Auth设置了安全配置。我的问题是,当我向基本的经过身份验证的URL发出请求时 使用有效的用户名和密码,它成功地对我进行身份验证,并将数据存储在cassandra中

然后,我希望必须通过/api/login为所有其他请求URL生成一个令牌,并将其添加到Authorization:Bearer{token}头中

但是,如果我已经通过基本身份验证,那么我就可以访问其他URL(受JWT身份验证保护),而无需在请求中使用令牌

当我在没有使用基本身份验证的情况下访问受JWT保护的URL时,我必须在标头中发送令牌,它将按预期工作

我应该期待这个吗?我相信,即使我通过一个端点的基本身份验证进行了身份验证,我仍然必须在请求中为所有其他受保护的JWT端点发送令牌

我找到了这个答案:

还有这篇文章:

并尝试实施解决方案,但所解释的问题仍然存在

安全配置类如下所示:

@Configuration
@EnableWebSecurity
public class SecurityHttpConfig extends WebSecurityConfigurerAdapter {

    @Configuration
    @Order(1)
    public static class BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter {

        @Value("${basic.auth.user}")
        private String basicAuthUsername;

        @Value("${basic.auth.password}")
        private String basicAuthPassword;

        @Value("${crashboxx.consume.endpoint}")
        private String crashBoxxConsumeEndpoint;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests().antMatchers("/v1/crash/consumeCrashBoxxEvent").hasRole("ADMIN").and()
                    .httpBasic().authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);// We don't need sessions to be created.
        }

        @Bean
        public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
            return new CustomBasicAuthenticationEntryPoint();
        }

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
            auth.inMemoryAuthentication().withUser(basicAuthUsername).password(encoder.encode(basicAuthPassword))
                    .roles("ADMIN");
        }

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

    @Configuration
    @Order(2)
    public static class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntryPoint unauthorizedHandler;

        @Autowired
        private JwtAuthenticationProvider jwtAuthenticationProvider;

        // Any endpoints that require no authorization should be added here..
        @Value("${api.login.endpoint}")
        private String loginEndpoint;

        @Autowired
        public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) {
            authenticationManagerBuilder.authenticationProvider(jwtAuthenticationProvider);
        }

        @Bean
        public JwtAuthenticationTokenFilter authenticationTokenFilterBean() {
            return new JwtAuthenticationTokenFilter();
        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity.csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated();

            httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
            httpSecurity.headers().cacheControl();
        }
    }
使用BasicAuthEntryPoint类:

public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    private static final Gson gson = new Gson();

    @Override
    public void commence(final HttpServletRequest request, final HttpServletResponse response,
            final AuthenticationException authException) throws IOException, ServletException {
        // Authentication failed, send error response.
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println(gson.toJson("HTTP Status 401 : " + authException.getMessage()));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("Realm");
        super.afterPropertiesSet();
    }
此外,JWT impl:

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Value("${jwt.header}")
    private String tokenHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        final String requestHeader = request.getHeader(tokenHeader);
        // Ensure Auth Header contains 'Bearer'
        if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
            String authToken = requestHeader.substring(7);
            JwtAuthentication authentication = new JwtAuthentication(authToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        chain.doFilter(request, response);
    }
我希望这是有道理的。。如果还有其他问题,请告诉我,但我似乎无法回避这个问题

我首先添加了“特殊情况”,这是基本身份验证的一个url,但仍然没有任何区别


感谢您在订单(1)的安全配置中发布的代码

@覆盖
受保护的无效配置(HttpSecurity http)引发异常{
http.csrf().disable().authorizeRequests().antMatchers(“/v1/crash/consumercrashboxxevent”).hasRole(“ADMIN”)和()
.httpBasic().authenticationEntryPoint(GetBasicAuthenticationPoint())和().sessionManagement()
.sessionCreationPolicy(sessionCreationPolicy.STATELESS);
}
如果这是您正在使用的确切代码,则不会咨询您的
@Order(2)
配置。它将是死配置。
让我解释一下
http.authorizeRequests()
=
http.antMatcher(“/**”).authorizeRequests()

在第一次配置中,您使用的是通配符,配置结果为

  • /v1/crash/consumercrashboxxevent
    如果用户经过身份验证且具有管理员角色,则可访问
  • 如果用户经过身份验证,则可访问URL的其余部分
让我猜猜发生了什么事
1.您正在点击URL
/v1/crash/consumercrashboxxevent
任何URL
,系统将提示您进行基本身份验证。
2.成功身份验证后,您可以访问任何URL,因为您是经过身份验证的用户

但是,如果我已经通过基本身份验证,那么我就可以访问其他URL(受JWT身份验证保护),而无需在请求中使用令牌

因为正如我所说,您可以访问任何URL,因为您是经过身份验证的用户

当我在没有使用基本身份验证的情况下访问受JWT保护的URL时,我必须在头中发送令牌,并且它可以按预期工作

检查是否没有您可以访问的令牌。因为一旦通过基本身份验证登录,就不会从服务器端注销(即使重新启动服务器)。只有关闭浏览器才能实现注销。所以您可以通过再次关闭和启动浏览器来测试它。并通过不发送JWT令牌进行测试。
还要确保您的请求到达JwtAuthenticationTokenFilter,将调试日志放入验证

因为在你的问题中有很多抽象,除非你发布完整的代码,否则很难准确预测到底发生了什么


如果我的预测与实际情况有偏差,请在评论中告诉我。

这是通过使用Praveen Kumar Lalasangi在上述回答中提供的信息解决的

configure
方法做了一点小改动就成功了。。更新内容如下:

@Override
    protected void configure(HttpSecurity http) throws Exception {
      http.csrf().disable()
      .antMatcher(crashBoxxConsumeEndpoint).authorizeRequests().anyRequest()
      .hasRole("ADMIN")
      .and().httpBasic().authenticationEntryPoint(getBasicAuthEntryPoint())
      .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

请提及您的登录点URL和crashBoxxConsumeEndpointURL@PraveenKumarLalasangi我已经用url的硬编码更新了代码您的所有请求url的模式是什么<代码>/v1/crash/**?让我知道URL受JWT保护auth@Alexander我仍然没有建议使用.antMatcher(“/allowedUrlsForFirstWebSecurityConfigurations/**”),因为我不知道您的完整URL。让我知道你的URL(你假设URL受JWT auth保护)嗨,我现在通过修改@Order(1)configure方法解决了这个问题!很高兴听到它被解决了。如果您已经添加/包含任何额外的配置来解决您的问题,请考虑写一个答案或评论。对于未来的读者来说,这里的OP只希望使用CRASBOXXXOXCOMME端点来验证用户,所以一阶配置只允许<代码>。对于基本身份验证和其他URL,使用第二顺序配置(JWT auth筛选器)