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

1u4esq0p  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(122)

最初,spring Security身份验证中的principal对象是一个字符串,它只包含用户id。通过定义自定义用户详细信息服务或自定义身份验证提供程序,并扩展spring Security中的用户对象,用户信息应该存储在principal对象中。但无论我选择哪一个,principal对象总是保持字符串。2为了安全起见,我们使用了带有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));
  }

}

这是我的Web安全配置:

@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总是返回同一个人,但我认为这不应该是一个问题。

gajydyqb

gajydyqb1#

声明CustomAuthenticationProvider只会将Authentication对象添加到安全上下文中。为了自定义安全上下文中所需的Principal对象,必须实现UserDetailsService
Baeldung是一个很好的引物。

相关问题