2017-02-26 74 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作爲價值。這是我的用戶登錄。 –

相關問題