当前位置: 首页 > 知识库问答 >
问题:

JWT Spring Security身份验证过滤器丢失头信息

乐正秦斩
2023-03-14

根据本文,我使用Spring Security基础使用JWT实现了REST Security-https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java

特别是,我有一个过滤器,可以使用请求的“授权”头中的令牌对用户进行身份验证:

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

public JwtAuthenticationFilter() {
    super("/**");
}

@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
    return true;
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

    String header = request.getHeader("Authorization");

    if (header == null || !header.startsWith("Bearer ")) {
        throw new JwtTokenMissingException("No JWT token found in request headers");
    }

    String authToken = header.substring(7);

    JwtAuthenticationToken authRequest = new JwtAuthenticationToken(authToken);

    return getAuthenticationManager().authenticate(authRequest);
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
        throws IOException, ServletException {
    super.successfulAuthentication(request, response, chain, authResult);

    // As this authentication is in HTTP header, after success we need to continue the request normally
    // and return the response as if the resource was not secured at all
    chain.doFilter(request, response);
}
}

所以,每次处理请求时,我的过滤器都不会在HttpServletRequest对象中找到授权和任何其他头信息,应用程序会给出用户未经身份验证的答案。当我停用JWT安全过滤器时,同一个请求中有所有的头。

有人知道如何解决这个问题吗?

我的配置文件是:

?xml version="1.0" encoding="UTF-8"?>
<beans:beans
    xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="
      http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-4.2.xsd
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

<!--activate @PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize annotations on any spring beans in the context-->
<global-method-security pre-post-annotations="enabled" />

<!--define the login and signup endpoints to skip security-->
<http pattern="/authenticate" security="none"/>

<!--we define the filter chain applied to all requests while adding two important configs: Entry point reference and -->
<!--setting the session creation to stateless (we do not want the session created for security purposes as -->
<!--we are using tokens for each request)-->
<http pattern="/**" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
    <!--We do not need csrf protection because our tokens are immune to it-->
    <csrf disabled="true"/>
    <!--we plug in our special authentication filter within the Spring’s predefined filter chain,-->
    <!--just before the form login filter-->
    <custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter"/>
</http>

<!--This bean is the declaration of our authentification filter; since it is extending Spring’s -->
<!--AbstractAuthenticationProcessingFilter, we need to declare it in XML to wire its properties -->
<!--(auto wire does not work here)-->
<beans:bean id="jwtAuthenticationFilter" class="by.eventcat.rest.security.JwtAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <!--The default success handler of AbstractAuthenticationProcessingFilter is not good enough for REST purposes -->
    <!--because it redirects the user to a success page; that is why we set our own here-->
    <beans:property name="authenticationSuccessHandler" ref="jwtAuthenticationSuccessHandler" />
</beans:bean>

<authentication-manager alias="authenticationManager">
    <!--The declaration of the provider created by the authenticationManager is used by our filter to authenticate users-->
    <authentication-provider ref="jwtAuthenticationProvider" />
</authentication-manager>

<beans:bean id="restAuthenticationEntryPoint" class="by.eventcat.rest.security.RestAuthenticationEntryPoint"/>
<beans:bean id="jwtAuthenticationProvider" class="by.eventcat.rest.security.JwtAuthenticationProvider"/>
<beans:bean id="jwtUtil" class="by.eventcat.rest.security.JwtUtil"/>

共有1个答案

陆弘光
2023-03-14

我已经添加到我的应用程序CORS配置中,这不仅会影响响应,还会影响请求。所以,在我的web.xml我补充道:

<!--CORS configuration--> 
<filter>
    <filter-name>corsFilter</filter-name>
    <filter-class>by.eventcat.rest.MyCorsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>corsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

MyCorsFilter是:

public class MyCorsFilter extends CorsFilter {

public MyCorsFilter() {
    super(configurationSource());
}

private static UrlBasedCorsConfigurationSource configurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.addAllowedOrigin("*");
    config.addAllowedMethod("*");
    config.addAllowedHeader("*");
    config.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return source;
}

}
 类似资料:
  • 问题内容: 前言 这是我第一次尝试过滤器,要小心。 项目介绍 我正在尝试为我们的一些应用程序最终确定SSO的构建,而且似乎步履维艰。我尝试连接的Webapp使用“身份验证”标头来确定应用程序内的用户凭据。我构建了一个Filter,希望在将标头传递到Web应用程序之前对其进行设置。 问题 该代码通过Eclipse验证,编译,加载到Tomcat,然后传递到Webapp。唯一缺少的是Authentica

  • 我在REST api中使用JWT承载身份验证方案。为了在成功身份验证后将jwt令牌返回给客户端,目前我在正文中使用访问令牌响应,如中所述https://www.rfc-editor.org/rfc/rfc6750#page-10 但是也需要在其他HTTP请求中返回令牌,例如已经存在正文的注册。因此,正在考虑为其使用“身份验证信息”标头。但是承载方案没有在任何地方指定“身份验证信息”标头。我应该使用

  • 我试图完成的是为我的 rest api 提供基于 jwt 令牌的身份验证。/api 下的所有内容只能使用令牌进行访问。 我在 Web 安全配置中具有以下配置方法: 这是过滤器: 我的问题是过滤器现在应用于每个url,而不仅仅是具有 /api前缀的url。 我知道我的“配置”方法可能是错误的,但它应该是什么样子?我想要完成的就是为/api路径使用过滤器。 1 个问题:为什么有两个值来配置将应用筛选器

  • Tweepy API请求twitter return me Twitter错误响应:状态代码=401。 这是我的实际代码: 我曾试图用tweepy软件包删除推文,并获得了所有必需的密钥。镊子包装不起作用吗?有人能帮我解决这个问题吗。

  • 我正在为用户进行LDAP身份验证。步骤是-1。当用户在登录屏幕上输入用户名时。2.请求转到LDAP服务器,并将尝试根据其相应的组验证用户 过滤器:=“(|(employeeNumber=deeps)(memberOf=CN=DEV_Admin,OU=LDAP,DC=TEMP,DC=com))” 这个过滤器工作正常,并给我相关组的员工详细信息。 现在,需求发生了变化- 当用户输入他的employee

  • 我实现了一个自定义的身份验证过滤器,效果很好。在设置会话并将身份验证对象添加到安全上下文后,我使用外部身份提供程序并重定向到最初请求的URL。 安全配置 过滤逻辑 目前,我的自定义过滤器(身份确认后)只需硬编码一个角色: 然后将该身份验证对象(上面返回)添加到我的SecurityContext,然后再重定向到所需的endpoint: SecurityContextHolder.getContext