![](/img/trans.png)
[英]How to configure multiple HttpSecurity with UserDetailsService using spring boot security?
[英]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.