我有一个需要以两种不同方式保护的API:
1) 对除1以外的所有请求URL使用JWT,该URL需要使用基本身份验证进行保护
2) 一个url的基本身份验证。
我已经为JWT和Basic Auth设置了安全配置。我的问题是,当我使用有效的用户名和密码请求基本的经过身份验证的URL时,它会成功地对我进行身份验证,并将数据存储在cassandra中。
然后,我希望必须通过/api/login为所有其他请求URL生成一个令牌,并将其添加到Authorization:Bearer{token}头中。。
但是,如果我通过Basic Auth进行了身份验证,那么我可以访问其他URL(受JWT auth保护),而无需在请求中添加令牌。
当我在没有使用基本身份验证的情况下访问受JWT保护的URL时,我必须在标头中发送令牌,它会按预期工作。。
我应该期待这个吗?正如我所相信的,即使我通过一个endpoint的基本身份验证进行了身份验证,我仍然应该在请求中为所有其他受保护的JWTendpoint发送令牌。。
我找到了这个答案:SpringBoot多重身份验证适配器
还有这篇文章:https://docs.spring.io/spring-security/site/docs/4.2.x/reference/htmlsingle/#multiple-httpsecurity
并尝试实施解决方案,但所解释的问题仍然存在。
安全配置类如下:
@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);
}
我希望这是有意义的。。如果还有其他问题,请告诉我,但我似乎无法回避这个问题。
我首先添加了“特殊情况”,这是基本身份验证的一个网址,但仍然没有任何区别。
谢谢
这是通过使用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);
}
您在@order(1)
的安全配置中发布的代码
@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);
}
如果这是您正在使用的确切代码,则不会咨询您的订单(2)配置。这将是死配置<让我解释一下http。authorizeRequests()。antMatcher(“/**”)。authorizeRequests()
在第一次配置中,您使用的是通配符,配置结果为
/v1/崩溃/consumeCrashBoxxEvent
如果用户经过身份验证,则访问URL的其余部分
让我猜猜发生了什么!
1.您正在点击URL/v1/崩溃/consumeCrashBoxxEvent
或任何URL
您将被提示进行基本身份验证。
2.身份验证成功后,您可以访问任何URL,因为您是经过身份验证的用户。
但是,如果我通过Basic Auth进行了身份验证,那么我可以访问其他URL(受JWT auth保护),而无需在请求中添加令牌。
因为正如我所说,您可以访问任何URL,因为您是经过身份验证的用户
当我在没有使用基本身份验证的情况下访问受JWT保护的URL时,我必须在标头中发送令牌,它会按预期工作
检查您是否可以访问没有令牌。因为一旦您通过基本身份验证登录,服务器端就不会注销(即使您重新启动服务器)。只有关闭浏览器才能实现注销。因此,您通过关闭并再次启动浏览器来测试它。并通过不发送JWT令牌来测试它。
还要确保您的请求到达JwtAuthentiationTokenFilter,放置调试日志进行验证。
因为在您的问题中有很多抽象,除非发布完整的代码,否则很难准确预测发生了什么。
如果我的预测偏离实际,请在评论中告诉我。
我一直在努力遵循这个教程: https://www.baeldung.com/spring-security-basic-authentication 我创建了几个restendpoint,如下所示: 现在的问题是,每当我试图发送POST请求时,我都会得到以下错误消息: HTTP状态401-访问此资源需要完全身份验证 我尝试了两种方法来发送请求,一种是通过邮递员 1.1 401 set-cooki
问题内容: 从HttpClient 4.3开始,我一直在使用HttpClientBuilder。我正在连接到具有基本身份验证的REST服务。我将凭据设置如下: 但是,这不起作用(我正在使用的REST服务返回401)。怎么了? 问题答案: 从此处的 抢先身份验证 文档中: http://hc.apache.org/httpcomponents-client- ga/tutorial/html/aut
我想使用Spring Cloud实现OAuth2的令牌刷新。 我可以使用以下有效负载通过向发送请求来创建令牌: 但对于刷新令牌,则使用相同的路径。我还需要将用户名和密码发送到标题中,但我没有它们。我可以使用以下负载使用刷新令牌创建一个新令牌: Github代码
我正在尝试将我的spring boot应用程序配置为登录zipkin服务器。问题是,该服务器受代理(具有基本身份验证)保护,我找不到任何描述如何使用spring sleuth配置授权的文档。 我尝试过使用这种配置: 但没有成功,日志显示: 我试过卷发,效果很好。 有人已经成功地用spring sleuth配置了身份验证吗?
身份验证 PDF版下载 企业应用中的URL链接可以通过OAuth2.0验证接口来获取员工的身份信息。 通过此接口获取员工身份会有一定的时间开销。对于频繁获取员工身份的场景,建议采用如下方案: 企业应用中的URL链接直接填写企业自己的页面地址; 员工跳转到企业页面时,企业校验是否有代表员工身份的cookie,此cookie由企业生成; 如果没有获取到cookie,重定向到OAuth验证链接,获取员工
目前我正在开发一个Java工具,它应该可以更新Confluence服务器页面。使用Curl一切都像一个符咒,但是当使用Postman或Java代码(HttpClient Java11)时,我得到了一个 HTTP状态401–未经授权 反应。 在下面的语句中使用curl curl--basic-u user:password-X PUT-H“内容类型:application/json”-d“@test