无法自定义主体对象,无论它如何始终保持字符串

时间:2017-03-01 07:04:05

标签: spring spring-boot spring-security oauth-2.0

最初,spring security的身份验证中的主要对象是一个字符串,它只包含用户ID。通过定义自定义用户详细信息服务或自定义身份验证提供程序并在spring security中扩展用户对象,用户信息应存储在主体对象中。但无论我选择哪一个,主要对象总是保持一个字符串。为了安全起见,我们使用带有oauth2的身份验证服务器。

这是具有自定义身份验证提供程序的版本。我已经找到了一个提示,一个名为forcePrincipleAsString的字段可能是我的问题的原因,虽然它应该最初设置为false,并且我使用的自定义身份验证提供程序没有这样的字段。

这是我的自定义身份验证提供程序:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    public Authentication authenticate(Authentication authentication ) throws AuthenticationException {
        String password = authentication.getCredentials().toString().trim();
        SecurityUser appUser = new SecurityUser();
        return new UsernamePasswordAuthenticationToken(appUser, password, new ArrayList<>());
  }
  @Override
  public boolean supports(Class<? extends Object> authentication) {
      return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
  }

} 

这是我的网络安全配置:

@Configuration
@EnableOAuth2Sso
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan("edu.kit.tm.cm.bamsg.bffweb.iamservice")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String REALM = "bam";

    @Autowired
    private CustomAuthenticationProvider authProvider; 

    @Autowired
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.authenticationProvider(authProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
            .logout()
            .and()
            //endpoints without authentication
            .authorizeRequests().antMatchers("/logged", "/userData").permitAll()
            .and()
            // default with authentication
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .csrf()
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}

    @Bean
    public OAuth2FeignRequestInterceptor oAuth2FeignRequestInterceptor(OAuth2ClientContext context, OAuth2ProtectedResourceDetails details) {
        return new OAuth2FeignRequestInterceptor(context, details);
    }
    // I added this code from an advice, but it didn't help
    @Bean
    BasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
        BasicAuthenticationEntryPoint basicAuth = new BasicAuthenticationEntryPoint();
        basicAuth.setRealmName(REALM);
        return basicAuth;
    }
}

扩展用户类看起来像这样:

public class SecurityUser extends User{

    String firstName;
    String name;
    String password;

    private static final long serialVersionUID = 1L;

    public SecurityUser() {
        super("user", "none", new ArrayList<>());
        firstName = "Rainer";
        name = "Schlund";
        password = "meins";
    }

    public String getRole(){
        return "Student";
    }


}

至少在使用System.out.println在代码行进行身份验证之后,应该已经调用了自定义服务,但不幸的是,它们不是。从未到过自定义服务中的断点,并且主体仍然是字符串而不是我的自定义用户:

@ComponentScan("edu.kit.tm.cm.bamsg.bffweb.iamservice")
@RestController
@RequestMapping("/api/theses")
public class ThesisController {

    @Autowired
    private ThesisClient thesisClient;

    @Autowired
    private ThesisPersonLinker linker;

    @Autowired
    private ThesisPersonFilter filter;

    @GetMapping
    @PreAuthorize("hasRole('theses')")
    public ResponseEntity<Collection<ThesisFrontendDTO>> findAllTheses() {
       System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());

代码包含一些用于测试的简化,例如SecurityPerson总是返回同一个人,但我认为这应该不是问题。

1 个答案:

答案 0 :(得分:1)

声明CustomAuthenticationProvider只会将Authentication对象添加到安全上下文中。为了在安全上下文中自定义所需的Principal对象,您必须实现UserDetailsService

Baeldung是一本很好的入门书。