簡體   English   中英

如何在Spring Boot中配置多個安全上下文?

[英]How to configure multiple security contexts in Spring Boot?

我正在使用Spring Security運行Spring-Boot 2應用程序。 我希望應用程序獨立處理不同路徑的安全性,比如說:

  • 我想對/api-spec/**使用基本身份驗證(僅此路徑)
  • /api/**的自定義JWT身份驗證

我的所有嘗試都導致整個應用程序都啟用了基本身份驗證,而不僅是/api-spec/**啟用了,這絕對不是我想要的。

我的安全配置如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
            .antMatchers(HttpMethod.GET, "/api-spec/**")
            .authenticated().and().httpBasic()
            .and().authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .addFilter(new JwtAuthenticationFilter(...))
            .addFilter(new JwtAuthorizationFilter(...))
            .httpBasic().disable();
}

我還嘗試了使用多個WebSecurityConfigurerAdapter的運氣,它們具有相同的效果。

是否可以告訴Spring將不同的安全上下文用於不同的路徑?

您必須自定義JWT,使其僅適用於請求/api-spec/**

我的所有嘗試都導致整個應用程序都啟用了基本身份驗證,而不僅是/ api-spec / **

您有.antMatchers(HttpMethod.GET, "/api-spec/**").authenticated()用於基本身份驗證,但未指定對/api/**做什么。 由於您具有.anyRequest().authenticated()因此Spring將對/api/**所有請求進行身份驗證(此處為所有請求)


JWT自定義(只是一個我不知道的關於.addFilter(new JwtAuthenticationFilter(...))的想法)

這里,僅對於包含 /api-spec/**/ /api/**的請求,才需要JWT令牌/api-spec/**/不需要JWT令牌。 達到要求的代碼是

//JwtAuthenticationEntryPoint.java
if(request.getRequestURI().contains("api-spec")==true)
{
    System.out.println("JWT Token is not required");
    chain.doFilter(request, response);
}

//JwtRequestFilter.java
if(request.getRequestURI().contains("api-spec")==false) 
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); 

JwtAuthenticationEntryPoint.java

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {

    private static final long serialVersionUID = -7858869558953243875L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws IOException {

        System.out.println("Entry Request: "+request.getRequestURI());
        System.out.println("Entry Contain: "+request.getRequestURI().contains("api-spec"));
        if(request.getRequestURI().contains("api-spec")==false) 
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");    
    }
}

JwtRequestFilter.java

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String requestTokenHeader = request.getHeader("Authorization");
        System.out.println("JWT Request: "+request.getRequestURI());
        System.out.println("JWT Contain: "+request.getRequestURI().contains("api-spec"));
        String username = null;
        String jwtToken = null;

        if(request.getRequestURI().contains("api-spec")==true)
        {
            System.out.println("JWT Token is not required");
            chain.doFilter(request, response);
        }
        else 
            if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ") ) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {

                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM