2017-02-26 73 views
0

我需要一些额外的数据在用户身份验证用户的详细信息。所以我写了一个自定义详细信息服务,并作为第二种方法定制身份验证提供程序来丰富用户对象中的数据。但是安全上下文中的主要对象保留一个字符串,而不是成为所需的用户对象,并且当我设置断点时,我的自定义详细信息服务和身份验证porvider看起来像这个代码从来没有被spring使用,尽管我的自定义类被列在弹簧验证管理器构建器。自定义用户详细信息和自定义身份验证提供程序从不称为

这是我的自定义用户信息服务:

package edu.kit.tm.cm.bamsg.bffweb.iamservice; 

import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 

import java.util.HashSet; 
import java.util.Set; 

/*** @author schlund*/ 

public class CustomStudentDetailsService implements UserDetailsService { 

    private SecurityUserRepository securityUserRepository; 

    public CustomStudentDetailsService(SecurityUserRepository userSecurityRepository){ 
     this.securityUserRepository=userSecurityRepository; 
    } 


    @Override 
    public SecurityUser loadUserByUsername(String kitID) throws UsernameNotFoundException { 

     try { 
      SecurityUser securityPerson = securityUserRepository.findByUsername(kitID); 
      if (securityPerson == null) { 
       return null; 
      } 
      return securityPerson; 
     } 
     catch (Exception e){ 
     throw new UsernameNotFoundException("User not found"); 
     } 
    } 

    private Set<GrantedAuthority> getAuthorities(SecurityUser securityPerson){ 
     Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); 
     GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(securityPerson.getRole()); 
     authorities.add(grantedAuthority); 
     return authorities; 
    } 

} 

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

package edu.kit.tm.cm.bamsg.bffweb.iamservice; 

import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.stereotype.Component; 

@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, null); 
    } 
    @Override 
    public boolean supports(Class<? extends Object> authentication) { 
     return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); 
    } 

} 

这是我的web安全配置:

package edu.kit.tm.cm.bamsg.bffweb; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; 
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.oauth2.client.OAuth2ClientContext; 
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; 
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; 
import org.springframework.security.web.csrf.CookieCsrfTokenRepository; 

import edu.kit.tm.cm.bamsg.bffweb.iamservice.*; 

@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); 
    } 

    @Bean 
    BasicAuthenticationEntryPoint getBasicAuthEntryPoint() { 
     BasicAuthenticationEntryPoint basicAuth = new BasicAuthenticationEntryPoint(); 
     basicAuth.setRealmName(REALM); 
     return basicAuth; 
    } 
} 

而且至少在使用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()); 

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

package edu.kit.tm.cm.bamsg.bffweb.iamservice; 

import org.springframework.security.core.userdetails.User; 


public class SecurityUser extends User{ 

    String firstName; 
    String name; 
    String password; 

    private static final long serialVersionUID = 1L; 

    public SecurityUser() { 
     super("user", "none", null); 
     firstName = "Rainer"; 
     name = "Schlund"; 
     password = "meins"; 
    } 

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


} 

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

+1

是的,我使用Spring启动,并且是执行WebSecurityConfig,这是我可以检查我的自定义类是否在Spring身份验证管理器生成器中列出的位置。 –

回答

0

如果您希望Spring安全使用您的身份验证提供程序,则需要提供一些用于提供身份验证凭据的入口点。下面是例子WebSecuritConfig类:

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@ComponentScan 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    private static final String REALM = "realm"; 

    @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() 
      // default with authentication 
      .authorizeRequests().anyRequest().authenticated() 
      .and() 
      .csrf() 
      .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 
      .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()); 
    } 

    @Bean 
    BasicAuthenticationEntryPoint getBasicAuthEntryPoint() { 
     BasicAuthenticationEntryPoint basicAuth = new BasicAuthenticationEntryPoint(); 
     basicAuth.setRealmName(REALM); 
     return basicAuth; 
    } 

} 

而且你需要更改SecurityUser构造,因为你不能为null当局传递给超构造函数:

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

当您提供认证供应商,未使用的UserDetailsS​​ervice。所以你需要在auth provider中使用它。

+0

添加了示例中给出的基本身份验证入口点,删除了安全用户中的空值并删除了自定义详细信息服务。仍然主要是一个字符串,而不是所需的安全用户。 –

+0

在身份验证提供程序中,它将是用户名,但请在您的休息控制器中使用'''SecurityContextHolder.getContext()。getAuthentication()'''。你会看到Principal是一个SecurityUser对象。 – hya

+0

不幸的是,它仍然是一个字符串与ufeug作为价值。这是我的用户登录。 –

相关问题