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

未调用自定义Spring UserDetailsService

陶烨赫
2023-03-14

我试图为当前登录的用户添加一些自定义数据,所以我发现我可以实现自己的UserDetailsService并将其插入Spring中,但它从未被调用,我总是以用户名字符串的形式获得主体。

我有我的UserDetailsService实现:

@Service
public class UserDetailServiceImpl implements UserDetailsService {

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    ...
  }
}

我的UserDetails实现:

import org.springframework.security.core.userdetails.User;

public class LoggedInUser extends User {
...
}

并尝试通过多种方式在config(SecurityConfiguration)中设置它:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
      @Autowired
      private CustomAuthenticationProvider customAuthProvider;
      @Autowired
      private UserDetailsService userDetailServiceImpl;
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthProvider);
        auth.userDetailsService(userDetailServiceImpl).passwordEncoder(passwordService.getPasswordEncoder());
      }
...
}
@Autowired
  protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider);
    auth.userDetailsService(userDetailServiceImpl).passwordEncoder(passwordService.getPasswordEncoder());
  }
@Override
  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailServiceImpl();
  }

共有1个答案

严嘉良
2023-03-14

ILya Cyclone的评论是找出错误所在的关键,在再次检查CustomAuthenticationProvider之后,我注意到,当返回数据时,您可以指定Principal,它不需要仅仅是用户名,但是您可以在那里添加自定义的UserDetails,因为自定义的UserDetailsService没有被调用,这是我假设它总是被调用的错误。

因此,最终这就足以使自定义AuthenticationProvider与自定义UserDetails:

@Service
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private UserService userService;

  @Autowired
  private PasswordService passwordService;

  @Override
  public Authentication authenticate(Authentication auth) throws AuthenticationException {
    String username = auth.getName();
    String password = auth.getCredentials().toString();

    User user = userService.getUserWithPermissionsByName(username);
    if (user == null) {
      throw new BadCredentialsException("invalid_username_or_pass");
    }

    if (!passwordService.passwordsMatch(password, user.getPassword())) {
      throw new BadCredentialsException("invalid_username_or_pass");
    }

    String[] permissions = user.getPermissions().stream().map((p) -> p.getName()).toArray(String[]::new);
    List<GrantedAuthority> grantedAuths = AuthorityUtils.createAuthorityList(permissions);
    return new UsernamePasswordAuthenticationToken(new LoggedInUser(user.getName(), user.getPassword(), true, true, true, true, grantedAuths, user.getId()),
        password, grantedAuths);
  }

  @Override
  public boolean supports(Class<?> auth) {
    return auth.equals(UsernamePasswordAuthenticationToken.class);
  }
}
 类似资料:
  • 在我的Spring Boot项目中,我创建了一个自定义注释,其中validator扩展了ConstraintValidator,以验证RequestBody中的一些字段。注释对于非嵌套字段可以很好地工作,但对于嵌套字段不调用验证器。 我的注释如下所示: 我的验证类: 它在这样的情况下工作正常: 但是当放在嵌套对象上时,不会调用验证器: 类在我的中的用法: 关于如何解决这个问题有什么想法吗?我已经尝

  • 这是我设置适配器的方式: 我正在寻找一个解决方案,从昨天开始,我已经阅读了所有关于StackOverflow的帖子,但没有一个与我的问题相匹配。所以我想知道,它是否可以来自LinkedHashMap<...> 编辑:这是我的布局r.layout.etat_piece_item

  • 尝试使用自定义userDetailsService学习Spring Security性并面临以下问题 访问受限页(/admin或/user)时,spring security将启动并显示登录页。 但在使用正确的用户名和密码提交登录页后,在调用自定义userDetailsService实现中的loadUserByUsername方法之前,将直接显示拒绝访问页。 在日志中,只有异常--在访问受限页面时

  • 我有一个不能用Gson正确序列化的类(类只是name和HashMap),所以我编写了一个自定义序列化程序来从HashMap中打印名称和键值对。 此外,这是实际打印的内容,序列化整个对象并不像我所期望的那样工作,也不只是直接打印对象。 任何帮助都将不胜感激。

  • 我正在使用。Net framework 4.6.1和Swashback版本5.3.2在我的WebApi项目中。Swagger UI没有提供将输入作为请求主体发送到使用自定义模型绑定器的my POST Api的选项。 -使用的模型: -使用的API Post方法: -使用的活页夹型号: 我面临以下问题: > 当我们在post方法中使用“ModelBinder”时,Swagger UI显示这个屏幕,其

  • $this->db->call_function(); 这个方法用于执行一些 CodeIgniter 中没有定义的 PHP 数据库函数,而且 使用了一种平台独立的方式。举个例子,假设你要调用 mysql_get_client_info() 函数,这个函数 CodeIgniter 并不是原生支持的,你可以这样做: $this->db->call_function('get_client_info')