简体   繁体   English

控制器中的身份验证对象错误 [Spring-Boot]

[英]Wrong Authentication-Object in Controller [Spring-Boot]

I'm pretty new to Spring-Boot.我对 Spring-Boot 很陌生。 I have tried to block certain routes, permit some and implement authentication for them.我试图阻止某些路由,允许某些路由并为它们实施身份验证。 This works so far, but somehow I want to get the user who makes the request.到目前为止,这有效,但不知何故我想得到提出请求的用户。

My WebSecurityConfig:我的网络安全配置:

@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);
            }
        });
    }
}

The TokenFilter:令牌过滤器:

@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);
    }

}

The Authentications:认证:

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();
        }
    }

I also tried to override the Authentication in the SecurityContextHolder with the AuthorizedUser Object:我还尝试使用 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);
        }
    });
}

But this hasn't worked either.但这也没有奏效。 I have tried to access the User with the following methods:我尝试使用以下方法访问用户:

@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
}

It is because of @Component annotation on JwtTokenFilter class.这是因为JwtTokenFilter类上的@Component注释。 Remove that and you will be good to go.删除它,你会很高兴。 You are already defining that as a @Bean in your WebSecurityConfig class.您已经在WebSecurityConfig@Bean其定义为WebSecurityConfig Since you have @Component on the class it is running after the AuthenticationProvider code overriding the AuthenticatedUser set in SecurityContext with JwtAuthentication由于您在@Component上有@Component ,它在AuthenticationProvider代码使用JwtAuthentication覆盖SecurityContext设置的AuthenticatedUser之后运行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM