【问题标题】:Spring Security not returning UserDetails object, only usernameSpring Security 不返回 UserDetails 对象,只返回用户名
【发布时间】:2018-05-28 01:21:34
【问题描述】:

我以为我的授权实现已经完成,但是在尝试检索 UserDetails 对象时,我得到的只是用户名。

我正在使用具有以下详细信息的 oauth。

配置 AuthenticationManager:

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

完成后,我可以调试到我的 userDetailsS​​ervice:

@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        MyUser persistedUser = userRepository.findByEmail(email);

        if (persistedUser == null) {
            throw new UsernameNotFoundException(String.format("The email %s doesn't exist", email));
        }

        List<GrantedAuthority> authorities = new ArrayList<>();

        MyUser inMemoryUser = new MyUser(persistedUser.getEmail(), null, persistedUser.getEnabled(), false,
                false, false, authorities);

        return inMemoryUser;
    }
}

这完成得很好,我的客户取回了 JWT。但是我在调​​试后面的控制器方法时发现了以下问题。

@GetMapping
public @ResponseBody Iterable<Curriculum> getMyCurriculums(@AuthenticationPrincipal MyUser injectedUser) {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    MyUser principle = (MyUser) auth.getPrincipal();
    return curriculumService.findByUser(principle);
}

在这种情况下,injectUser = null,auth 是一个 OAuth2Authentication,principal 是一个字符串 - 用户名。应该是我的用户

【问题讨论】:

  • 而你的问题是...... ???

标签: spring spring-security oauth


【解决方案1】:

您应该配置 Spring Security 以将 jwt 令牌解码为 MyUser 对象。

首先定义一个自定义的OAuth2Authentication来封装MyUser

public class OAuth2AuthenticationUser extends OAuth2Authentication {

    private MyUser myUser;

    public OAuth2AuthenticationUser(OAuth2Request storedRequest, Authentication userAuthentication) {
        super(storedRequest, userAuthentication);
    }

    public MyUser getMyUser() {
        return myUser;
    }

    public void setMyUser(MyUser) {
        this.myUser= myUser;
    }
}

然后在一个安全配置类中配置jwt令牌解码如下:

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey("SIGNING_KEY");
    converter.setAccessTokenConverter(getAuthenticationAccessTokenConverter());
    return converter;
}

private DefaultAccessTokenConverter getAuthenticationAccessTokenConverter() {
    return new DefaultAccessTokenConverter() {
        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
            OAuth2Authentication authentication = (OAuth2Authentication) super.extractAuthentication(map);

            OAuth2AuthenticationUser authenticationUser =
                    new OAuth2AuthenticationUser(authentication.getOAuth2Request(), authentication.getUserAuthentication());

            MyUser myUser = new MyUser();

            // Example properties
            myUser.setId(map.get("id") != null ? Long.valueOf(map.get("id").toString()) : null);
            myUser.setUsername(map.get("user_name") != null ? map.get("user_name").toString() : null);
            myUser.setFullName(map.get("fullName") != null ? map.get("fullName").toString() : null);
            myUser.setCustomerId(map.get("customerId") != null ? Long.valueOf(map.get("customerId").toString()) : null);
            myUser.setCustomerName(map.get("customerName") != null ? map.get("customerName").toString() : null);

            // More other properties

            authenticationUser.setMyUser(myUser);

            return authenticationUser;
        }
    };
}

然后您可以从 Spring Security 上下文中访问MyUser 对象,如下所示:

private static MyUser getMyUser() {
    OAuth2AuthenticationUser authentication = (OAuth2AuthenticationUser) SecurityContextHolder.getContext().getAuthentication();
    return (authentication != null && authentication.getMyUser() != null ? authentication.getMyUser() : new MyUser());
}

这非常适合无状态环境,因为对用户详细信息的数据库访问被最小化并且您只需要 jwt 令牌。

【讨论】:

猜你喜欢
  • 2012-02-21
  • 2019-08-25
  • 2011-07-12
  • 1970-01-01
  • 2017-10-17
  • 2014-02-15
  • 2020-03-10
  • 2016-04-27
  • 2023-04-03
相关资源
最近更新 更多