Java Spring Security 自定义 UserDetailsS​​ervice 和自定义 User 类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25383286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:17:13  来源:igfitidea点击:

Spring Security custom UserDetailsService and custom User class

javaspringsecurityjpaspring-security

提问by jvecsei

I am trying to save additional data in de user principal object.

我正在尝试在用户主体对象中保存其他数据。

What i did was:

我所做的是:

implement the "UserDetails" interface to my existing user class where my additional data is saved ( like email address etc. ).

将“UserDetails”接口实现到我现有的用户类,在其中保存我的附加数据(如电子邮件地址等)。

@Entity
public class User implements UserDetails {

Then i created a UserDetailsService implementation:

然后我创建了一个 UserDetailsS​​ervice 实现:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    UserDAO userDAO;

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        User user = userDAO.findOneByUsername(username);
        if (user == null)
            throw new UsernameNotFoundException("username " + username
                    + " not found");

        System.out.println("---------------------> FOUND ------------->"
                + user.getEmail());

        return user;
    }

}

Last step was to add the UserDetailsService in my Security configuration.

最后一步是在我的安全配置中添加 UserDetailsS​​ervice。

@Configuration
@EnableWebMvcSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
UserDetailsService userDetailsService;



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

}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.userDetailsService(userDetailsService());
// ...
}

@Override
protected UserDetailsService userDetailsService() {
    return userDetailsService;
}

I see in my console that "loadUserByName" gets called twice ( because of the "Found" output ).

我在控制台中看到“loadUserByName”被调用了两次(因为“Found”输出)。

When i try to access the principal object in my controller ->

当我尝试访问控制器中的主体对象时 ->

System.out.println(SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal());

I dont get my additional data. When i try to cast it to my User object i get a could not cast exception.

我没有得到我的额外数据。当我尝试将它转换为我的 User 对象时,我得到了一个无法转换的异常。

Is there anything I am missing??

有什么我想念的吗??

Thank you in advance.

先感谢您。

采纳答案by jvecsei

Ok. My problem was hidden in the code i didnt post.

好的。我的问题隐藏在我没有发布的代码中。

I thought this detailsService is only to get additional details but it is used for the login itself.

我认为这个 detailsS​​ervice 只是为了获取额外的细节,但它用于登录本身。

I had "jdbcAuthentication" configured additionally and spring seemed to use this always.

我另外配置了“jdbcAuthentication”,spring 似乎总是使用它。

Now that i only got the detailsService configured everything works fine.

现在我只配置了 detailsS​​ervice,一切正常。

edit.:

编辑。:

so i only had to delete this code:

所以我只需要删除这段代码:

auth.jdbcAuthentication() .dataSource(dataSource)
     * .passwordEncoder(passwordEncoder) .usersByUsernameQuery(
//   ....

And now it also works with my code in the question above.

现在它也适用于我在上面问题中的代码。

回答by hleb.albau

Create Extention class:

创建扩展类:

public class CustomUserDetails extends org.springframework.security.core.userdetails.User{

    private User user;

    public CustomUserDetails(User user, Collection<? extends GrantedAuthority> authorities) {
        super(user.getName(), user.getPassword(), authorities);
        this.user = user;
    }

    public CustomUserDetails(User user, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
        super(user.getName(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        this.user = user;
    }

    public User getUser() {
        return user;
    }
}

Than add it to UserDetailsService:

然后将其添加到 UserDetailsS​​ervice:

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
    UserDetails userDetails = null;
    User user = userService.getByLogin(login);
    userDetails = new CustomUserDetails(user,
                true, true, true, true,
                getAuthorities(user.getRole()));

    return userDetails;
}

Get it!

得到它!

 (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()