2017-02-26 15 views
0

認証されたユーザーのユーザーの詳細には、いくつかの追加データが必要です。だから、私はカスタム詳細サービスを書いて、第2のアプローチとしてカスタム認証プロバイダを使用して、ユーザオブジェクト内のデータを充実させました。しかし、セキュリティコンテキストの主なオブジェクトは、目的のユーザーオブジェクトになる代わりに文字列のままです。ブレークポイントを設定すると、私のカスタム詳細サービスと認証コードが設定されます。スプリング認証マネージャービルダー。カスタムユーザーの詳細とカスタム認証プロバイダが呼び出されることはありません

これは私のカスタムユーザー詳細サービスです:

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

はい私は春のブートを使用し、はいWebSecurityConfigが実行されます。これは、カスタマイズされたクラスがスプリング認証マネージャービルダーにリストされていることを確認できる場所です。 –

答えて

0

認証プロバイダを使用するには、認証情報を入力するためのエントリポイントを用意する必要があります。ここで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; 
    } 

} 

そして、あなたはあなたがスーパーコンストラクタにnullを当局に渡すことはできませんので、SecurityUserコンストラクタを変更する必要があります:あなたは認証プロバイダを提供する場合

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

、UserDetailsS​​erviceが使用されていません。したがって、認証プロバイダで使用する必要があります。

+0

例のように基本認証エントリポイントを追加し、セキュリティユーザのnull値を削除し、カスタム詳細サービスを削除しました。依然としてプリンシパルは文字列であり、希望するセキュリティユーザーではありません。 –

+0

認証プロバイダではユーザ名になりますが、残りのコントローラでは '' 'SecurityContextHolder.getContext()。getAuthentication()' ''を使用してみます。プリンシパルがSecurityUserオブジェクトであることがわかります。 – hya

+0

不幸にも、値としてufeugを持つ文字列ではありません。それが私のユーザーログインです。 –

関連する問題