【问题标题】:Wrong Authentication-Object in Controller [Spring-Boot]控制器中的错误身份验证对象 [Spring-Boot]
【发布时间】:2019-12-30 04:33:20
【问题描述】:

我对 Spring-Boot 还是很陌生。我试图阻止某些路由,允许一些路由并为它们实施身份验证。到目前为止这工作,但不知何故我想得到提出请求的用户。

我的网络安全配置:

@Configuration
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtTokenService tokenService;

    public WebSecurityConfig(JwtTokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Bean
    public JwtTokenFilter tokenFilter() {
        return new JwtTokenFilter();
    }

    @Bean
    public SecurityContextHolderAwareRequestFilter securityContextHolderAwareRequestFilter() {
        return new SecurityContextHolderAwareRequestFilter();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers("/login", "/apply").permitAll()
                .anyRequest().authenticated();
        http.addFilterBefore(tokenFilter(), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();
    }

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder builder) {
        builder.authenticationProvider(new AuthenticationProvider() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String token = (String) authentication.getCredentials();
                return tokenService.decode(token).map(AuthenticatedUser::new).orElseThrow(JwtAuthenticationException::new);
            }

            @Override
            public boolean supports(Class<?> authentication) {
                return JwtAuthentication.class.equals(authentication);
            }
        });
    }
}

令牌过滤器:

@Component
public class JwtTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        String header = request.getHeader("Anima-Authentication-Token");
        if(header != null) {
            SecurityContextHolder.getContext().setAuthentication(new JwtAuthentication(header));
        }
        filterChain.doFilter(request, response);
    }

}

身份验证:

public class JwtAuthentication implements Authentication {

    private final String token;

    public JwtAuthentication(String token) {
        this.token = token;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public Object getCredentials() {
        return token;
    }

    @Override
    public Object getDetails() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return null;
    }

    @Override
    public boolean isAuthenticated() {
        return false;
    }

    @Override
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

    }

    @Override
    public String getName() {
        return null;
    }
}


public class AuthenticatedUser implements Authentication {

        private final AnimaUser user;

        public AuthenticatedUser(AnimaUser user) {
            this.user = user;
        }

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return new ArrayList<>();
        }

        @Override
        public Object getCredentials() {
            return null;
        }

        @Override
        public Object getDetails() {
            return null;
        }

        @Override
        public Object getPrincipal() {
            return user;
        }

        @Override
        public boolean isAuthenticated() {
            return true;
        }

        @Override
        public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

        }

        @Override
        public String getName() {
            return user.getName();
        }
    }

我还尝试使用 AuthorizedUser 对象覆盖 SecurityContextHolder 中的身份验证:

@Autowired
public void configureAuthentication(AuthenticationManagerBuilder builder) {
    builder.authenticationProvider(new AuthenticationProvider() {
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            String token = (String) authentication.getCredentials();
            return tokenService.decode(token).map(user - > {
                SecurityContextHolder.getContext().setAuthentication(new AuthenticatedUser(user));
                return new AuthenticatedUser(user);
            }).orElseThrow(JwtAuthenticationException::new);
        }

        @Override
        public boolean supports(Class<?> authentication) {
            return JwtAuthentication.class.equals(authentication);
        }
    });
}

但这也没有奏效。我尝试使用以下方法访问用户:

@GetMapping("")
@ResponseBody
public String handle() {
    // This returns the JwtAuthentication, not the AuthenticatedUser
    return SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
}

@GetMapping("")
@ResponseBody
public String handle(Authentication authentication) {
    // authentication is null
}

@GetMapping("")
@ResponseBody
public String handle(Principle principle) {
    // principle is null
}

【问题讨论】:

    标签: java spring spring-boot spring-mvc spring-security


    【解决方案1】:

    这是因为 JwtTokenFilter 类上的 @Component 注释。删除它,你会很高兴。您已经在WebSecurityConfig 类中将其定义为@Bean。由于您在类上有@Component,它在AuthenticationProvider 代码覆盖SecurityContext 中设置的AuthenticatedUser 之后运行JwtAuthentication

    【讨论】:

      猜你喜欢
      • 2020-08-19
      • 2021-03-31
      • 1970-01-01
      • 2018-02-27
      • 2017-04-12
      • 1970-01-01
      • 2021-12-28
      • 2017-10-08
      • 1970-01-01
      相关资源
      最近更新 更多