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

Spring Security认证总是返回401

孙莫希
2023-03-14

我在Spring遇到了身份验证问题。我有身份验证筛选器扩展UsernamePasswordAuthenticationFilter。

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private final AuthenticationManager authenticationManager;
private final RefreshTokenProvider refreshTokenProvider;
private final AccessTokenProvider accessTokenProvider = new AccessTokenProvider();

public AuthenticationFilter(AuthenticationManager authenticationManager, RefreshTokenProvider refreshTokenProvider) {
    this.authenticationManager = authenticationManager;
    this.refreshTokenProvider = refreshTokenProvider;
    setFilterProcessesUrl(SecurityConstants.AUTH_SIGN_IN_PATH);
}


@Override
public Authentication attemptAuthentication(HttpServletRequest request,
                                            HttpServletResponse response) throws AuthenticationException {
    try {
        SingInRequest singInRequest = new ObjectMapper().readValue(request.getInputStream(), SingInRequest.class);

        UsernamePasswordAuthenticationToken authRequest =
                new UsernamePasswordAuthenticationToken(singInRequest.getUsername(), singInRequest.getPassword());

        return authenticationManager.authenticate(authRequest);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }


}

@Override
protected void successfulAuthentication(HttpServletRequest req,
                                        HttpServletResponse res,
                                        FilterChain chain,
                                        Authentication auth) throws IOException, ServletException {
    //

}

实现UserDetailsService

@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final PasswordEncoder encoder;
    private final UserQueryRepository userQueryRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userQueryRepository.findUserByUsername(username)
                .map(this::getUserDetails)
                .orElseThrow(() -> new UsernameNotFoundException("User with username " + username + " not found"));
    }

    private UserDetails getUserDetails(UserDto user) {
        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .authorities(convertAuthorities(user))
                .password(encoder.encode(user.getPassword()))
                .disabled(!user.isActive())
                .build();
    }

    private List<GrantedAuthority> convertAuthorities(UserDto user) {
        return user.getRoles().stream().map(role ->
                new SimpleGrantedAuthority(role.toString())
        ).collect(Collectors.toList());
    }
}

和SecurityConfig类

@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserQueryRepository userQueryRepository;
    private final RefreshTokenProvider refreshTokenProvider;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                .disable()
                .authorizeRequests()
                .antMatchers("/auth/**").permitAll()
                .antMatchers("/book/**").authenticated()
                .and()
                .addFilter(new AuthenticationFilter(authenticationManager(), refreshTokenProvider))
                .addFilter(new AuthorizationFilter(authenticationManager()))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl(passwordEncoder(), userQueryRepository);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        corsConfiguration.addAllowedOrigin("http://localhost:3000");
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

如果我尝试让邮递员发送具有良好凭据的身份验证请求,在调试器模式下一切正常(AuthFilter和UserDetailsService),但服务器返回401并且Authfilter中的成功身份验证方法不会调用。

收到的POST'/auth/sing-in'请求:

org.apache.catalina.connector.RequestFacade@27b774b2

servletPath:/auth/sing-in-pathInfo:null头:内容类型:应用程序/json用户代理:PostmanRuntime/7.25.0接受:/cache-control:no-cache-postman令牌:c5bb3320-9c22-4d3d-93e9-628fe0e6f82a主机:localhost:9000接受编码:gzip,deflate,br连接:保持活动内容长度:54

安全过滤链:[WebAsyncManagerIntegrationFilter SecurityContextPerISTence Filter HeaderWriterFilter LogoutFilter AuthenticationFilter AuthorizationFilter Request estCacheAware Filter SecurityContextHolderAware Request estFilter AnnamousAuthenticationFilter SessionManagementFilter ExceptionTranslationFilter SecurityInterceptor]

2020-06-13 20:52:42.048信息9956---[nio-9000-exec-2]组织。mongodb。驾驶员连接:打开连接[connectionId{localValue:2,serverValue:126}]到127.0.0.1:27017 2020-06-13 20:52:42.258信息9956-[nio-9000-exec-2]Spring Security调试器:

收到POST'/error'的请求:

org.apache.catalina.core.ApplicationHttpRequest@fafe057

servletPath:/错误路径信息:空标头:内容类型:应用程序/json用户代理:PostmanRuntime/7.25.0接受:/缓存控制:无缓存邮递员令牌:c5bb3320-9c22-4d3d-93e9-628fe0e6f82a主机:localhost:9000接受编码:gzip,放气,br连接:保持活动内容长度: 54

安全过滤链:[WebAsyncManagerIntegrationFilter SecurityContextPerISTence Filter HeaderWriterFilter LogoutFilter AuthenticationFilter AuthorizationFilter Request estCacheAware Filter SecurityContextHolderAware Request estFilter AnnamousAuthenticationFilter SessionManagementFilter ExceptionTranslationFilter SecurityInterceptor]

共有1个答案

李振国
2023-03-14

successfulAuthentication()方法中没有任何内容。应该是这样的。

@Override
protected void successfulAuthentication(HttpServletRequest req,
                                        HttpServletResponse res,
                                        FilterChain chain,
                                        Authentication auth) throws IOException, ServletException {
        super.successfulAuthentication(req, res, chain, auth);
        chain.doFilter(req, res);
}

抱歉,我没有注意到“successfulAuthentication不调用”。您可以使用在调试模式下共享堆栈跟踪吗

@EnableWebSecurity(debug = true)
 类似资料:
  • 那还行。然后尝试调用创建用户(或执行其他操作),得到一个401未经授权的错误: 这不是包含令牌的正确方式吗?访问令牌是用于验证其他API调用的令牌吗?管理员帐户的令牌难道不应该用于通过主域对其他客户机的调用进行身份验证吗?是否需要在管理控制台更改主域中的某些设置?任何帮助都很感激。

  • 问题内容: 结果始终为1: 我在phpMyAdmin中运行了$ sql查询,它返回3,所以查询不是问题。$ vote_total全局初始化为0,因此1来自某个地方。我还需要提供什么其他信息来帮助我? 谢谢,瑞安 问题答案: 返回选定的行数,而不是特定行的字段。使用来获取您与您的查询选择的行: 您还可以用来获取一行并获取特定字段: 这将获取第一行(从零开始)并返回第一字段(从零开始)。

  • 问题内容: 我已经写了这段简单的代码: 在我的情况当属。谁能建议/建议出什么问题了? 问题答案: 错误检查和处理是程序员的朋友。检查初始化和执行cURL函数的返回值。并在失败的情况下包含更多信息: *在 手动状态: 成功返回cURL句柄,错误返回 FALSE 。 我观察到该函数在您使用其参数且无法解析域时会返回。如果未使用该参数,则该函数 可能 永远不会返回。但是,请务必始终进行检查,因为该手册并

  • 我使用Ehcache 2.6.8作为Spring Boot应用程序的一部分,作为Hibernate 4.3.11的二级缓存。我有一个JMX MBean,它允许我检查缓存的内容(如果您感兴趣,可以在这里查看)。 首先,我使用CacheManager名称来获取缓存列表。这很好。我可以用返回缓存。然后我调用。这很好,cacheName是“com.myapp.DomainObjectName”,键被列为“

  • 我试图打开一个文件进行解析(一个二进制文件),但是无论什么fopen()总是返回NULL。 我已经排除了几乎所有的东西,我有一个简单的测试脚本: trigger_error(var_export())的输出;是: 无论我为第二个fopen()选项指定什么标志,我都会得到相同的结果。 现在,明显的问题是该文件是否存在,以及我是否拥有读取该文件的权限?这两个问题的答案都是肯定的。我使用了相对路径和绝对

  • 在fetchplaces方法中,新的window.google.maps.places.PlacesService(map)总是返回null,并且Service.NearbySearch不会引发函数错误。 请帮忙。