【问题标题】:Spring Security loadUserByUsername() method is not called and authentication is sucess for incorrect password未调用 Spring Security loadUserByUsername() 方法,密码错误验证成功
【发布时间】:2020-08-17 14:24:44
【问题描述】:

我正在使用自定义 DAO UserDetailsS​​ervice 为我的 REST 服务实现 HTTP 基本身份验证方案。但是,即使我向 API 发送了不正确的密码(通过 POSTMAN),也不会调用此被覆盖的方法并且身份验证成功。任何输入都会有所帮助。

我的应用程序类

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
@EnableNeo4jRepositories("galaxy.spring.data.neo4j.repositories")
@EnableWebSecurity
public class SampleMovieApplication extends WebSecurityConfigurerAdapter {

    public static String REALM = "REALM";
    @Autowired
    private static UserService userService;

    public static void main(String[] args) {
        ConfigurableApplicationContext configContext = 
                SpringApplication.run(SampleMovieApplication.class, args);
        configContext.getBean(RepoInit.class).fillWithTestdata();

    }
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.cors().and()
                .authorizeRequests().anyRequest().fullyAuthenticated()
                .antMatchers("/galaxy/appuser/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/galaxy/appadmin/**").hasRole("ADMIN")
                .and().csrf().disable()
                .httpBasic().realmName("REALM").authenticationEntryPoint(getBasicAuthEntryPoint());

    }


    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
        return new CustomBasicAuthenticationEntryPoint();
    }

    @Override   
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        System.out.println("Calling authenticator");
      auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Bean
    public UserDetailsService userDetailsService() {
      System.out.println(userService == null ? " userservice is null " : "userservice is not null");
      return new UserDetailsServiceImp(userService);
    };

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


}

我的自定义 UserDetailsS​​ervice 类

public class UserDetailsServiceImp implements UserDetailsService {


    private UserService userService;

    public UserDetailsServiceImp(UserService userService) {
        this.userService = userService;
    }

    /*@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {


        DomainUser user = findUserbyUername(username);

        UserBuilder builder = null;
        if (user != null) {
          builder = org.springframework.security.core.userdetails.User.withUsername(username);
          builder.password(new BCryptPasswordEncoder().encode(user.getPassword()));
          builder.roles("ROLE_" + user.getBelongsTo().get(0).getDomainUserGroup().getAuthorityname());
        } else {
          throw new UsernameNotFoundException("User not found.");
        }

        return builder.build();
    } */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {


        System.out.println("called load method");
        DomainUser user = null;
        Set<GrantedAuthority> grantedAuthorities = null;
        try
        {
            user = findUserbyUername(username);
            if(user == null)
                throw new UsernameNotFoundException("User " + username  + " not available");

            grantedAuthorities = new HashSet<>();

            grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + 
            user.getBelongsTo().get(0).getDomainUserGroup().getAuthorityname()));

        }
        catch(Exception exp) {
            exp.printStackTrace();
        }
        System.out.println("Returning new userdetails");
        return new 
        org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), grantedAuthorities);
    }

    private DomainUser findUserbyUername(String username) {

        return userService.findByName(username);

    }
}

发布请求后的 SPRING SECURITY DEBUG LOG

2020-05-03 11:06:12.884  INFO 19868 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-05-03 11:06:12.884  INFO 19868 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-05-03 11:06:12.906  INFO 19868 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 22 ms
2020-05-03 11:06:12.930 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-05-03 11:06:12.930 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-05-03 11:06:12.930 DEBUG 19868 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@452579c9: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@452579c9: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN'
2020-05-03 11:06:12.930 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-05-03 11:06:12.930 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 4 of 12 in additional filter chain; firing Filter: 'CorsFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /galaxy/appadmin/usergroup' doesn't match 'GET /logout'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/galaxy/appadmin/usergroup'; against '/logout'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /galaxy/appadmin/usergroup' doesn't match 'PUT /logout'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /galaxy/appadmin/usergroup' doesn't match 'DELETE /logout'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.www.BasicAuthenticationFilter  : Basic Authentication Authorization header found for user 'admin'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache        : saved request doesn't match
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@452579c9: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /galaxy/appadmin/usergroup; Attributes: [fullyAuthenticated]
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@452579c9: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6a8bc4e6, returned: 1
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
2020-05-03 11:06:12.945 DEBUG 19868 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /galaxy/appadmin/usergroup reached end of additional filter chain; proceeding with original chain
 DomainUserGroup request is testgroup3
2020-05-03 11:06:13.126 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2020-05-03 11:06:13.126 DEBUG 19868 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@4aaae30c
2020-05-03 11:06:13.126 DEBUG 19868 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

    标签: spring-boot spring-security spring-security-rest


    【解决方案1】:

    在 SampleMovieApplication 类中添加这个...

    @Autowired
        public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
        }
    

    删除这个:

    @Override   
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            System.out.println("Calling authenticator");
          auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
        }
    

    【讨论】:

    • @rajesh 这个答案适合你吗?
    • 嗨 GolamMazid Sajib,这不起作用。我处于开发阶段,在 STS 环境中运行 Spring Boot 应用程序并通过 Postman 进行测试。当我第一次尝试使用不正确的密码时,我得到“HTTP 401 - Bad Credentials”。我第二次尝试使用正确的密码时,身份验证成功并调用了 REST API。此后,无论 HTTP Basic 中的密码是否正确,我发出的每个 REST 请求都会成功。这也是在进行此建议更改之前的行为。我在下面附上这个日志。
    • 无法将调试日志作为 cmets(太长)提交,因此作为编辑附加到您的帖子中。
    • @RajeshMel 显示有问题的身份验证入口点类 I ( CustomBasicAuthenticationEntryPoint )
    【解决方案2】:

    解决了这个问题。非常有趣的是,我们必须使控制器中的会话无效(就像我们正在注销)并以编程方式清除安全上下文。现在它是一致的并对每个请求进行身份验证。

    @PostMapping("/galaxy/appadmin/usergroup")
        public ResponseEntity<Object> createDomainUserGroup(@RequestBody 
                DomainUserGroup domainusergrp,HttpServletRequest request, HttpServletResponse response) {
            System.out.println(" DomainUserGroup request is "+ domainusergrp.getName());
            DomainUserGroup domainc = userGroupService.save(domainusergrp);
            URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").
                            buildAndExpand(domainc.getId()).toUri();
            SecurityContextHolder.clearContext();
            HttpSession session= request.getSession(false);
           if(session != null) {
               session.invalidate();
           }
    
            return ResponseEntity.created(location).build();
        }
    

    【讨论】:

      猜你喜欢
      • 2016-08-27
      • 2018-12-10
      • 2011-07-17
      • 2021-06-17
      • 1970-01-01
      • 2011-07-26
      • 2012-09-12
      • 1970-01-01
      • 2016-08-12
      相关资源
      最近更新 更多