代码之家  ›  专栏  ›  技术社区  ›  ralic

spring oauth,带有jwt自定义用户详细信息-在jwtaccesstokenconverter内设置主体

  •  0
  • ralic  · 技术社区  · 6 年前

    一些附加信息是从OAuth授权服务器发送的,这是自定义 UserDetails 在资源服务器上初始化,最好在springsecurity主体内。

    当前的方法是将用户名设置为主体,并将其他信息添加为此类身份验证对象的其他详细信息。

    public class CustomAccessTokenConverter extends JwtAccessTokenConverter{
    
        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
            OAuth2Authentication authentication = super.extractAuthentication(claims);
    
            CustomUserDetails userDetails = new CustomUserDetails ();
            userDetails.setUserId(((Integer)claims.get("id")).longValue());
            userDetails.setName((String) claims.get("name"));
            userDetails.setLastName((String) claims.get("lastName"));
    
            authentication.setDetails(userDetails);
    
            return authentication;
        }
    }
    

    这种方法的好处是我们可以从应用程序中的任何位置访问自定义用户详细信息。糟糕的是,pricipal对象只能是用户用户名,我们需要更多的代码来访问自定义用户详细信息。

    // preferable way   
    (UserAuthDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    
    // current solution
    (UserAuthDetails) ((OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails()).getDecodedDetails();
    

    有更干净的解决办法吗 JwtAccessTokenConverter 但仍然可以将主体设置为自定义用户详细信息,而不是将其设置为(无用的)用户名,并将附加信息作为身份验证对象的详细信息发送?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Nick K.    6 年前

    我不能说这是否是首选的解决方案,但在尝试自己解决相同的问题之后,我最终扩展了 DefaultUserAuthenticationConverter 是的。

    所以你可以这样做

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
      DefaultAccessTokenConverter defaultConverter = new DefaultAccessTokenConverter();
      defaultConverter.setUserTokenConverter(new CustomUserAuthenticationConverter());
    
      JwtAccessTokenConverter jwtConverter = new JwtAccessTokenConverter();
      converter.setAccessTokenConverter(defaultConverter);
      return converter;
    }
    

    那么DefaultUserAuthenticationConverter的可扩展性不是很强,因为大多数方法和属性都是私有的。但这里有一个例子

    public class CustomUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
    
      private static final String CUST_PROP = "custProp";
    
      @Override
      public Authentication extractAuthentication(Map<String, ?> map) {
        if (map.containsKey(USERNAME) && map.containsKey(CUST_PROP)) {
          String username = (String) map.get(USERNAME);
          String custProp = (String) map.get(CUST_PROP);
    
          CustomPrincipal principal = new CustomPrincipal();
          pricipal.setUsername(username);
          pricipal.setCustomProp(custProp);
    
          Collection<? extends GrantedAuthority> authorities = getAuthorities(map);
          return new UsernamePasswordAuthenticationToken(user, "N/A", authorities);
        }
        return null;
      }
    
      private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
        //Copy this method from DefaultUserAuthenticationConverter or create your own.
      }
    
    }