2015-02-24 55 views
1

我使用Spring Security與Waffle結合來驗證我的webapp的用戶。我配置的Spring Security具有以下配置:如何獲得用華夫餅認證的用戶的詳細信息?

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; 
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 

import waffle.servlet.spi.BasicSecurityFilterProvider; 
import waffle.servlet.spi.NegotiateSecurityFilterProvider; 
import waffle.servlet.spi.SecurityFilterProvider; 
import waffle.servlet.spi.SecurityFilterProviderCollection; 
import waffle.spring.NegotiateSecurityFilter; 
import waffle.spring.NegotiateSecurityFilterEntryPoint; 
import waffle.windows.auth.impl.WindowsAuthProviderImpl; 

@Configuration 
@EnableWebMvcSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private NegotiateSecurityFilterEntryPoint entryPoint; 

    @Autowired 
    private NegotiateSecurityFilter filter; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.exceptionHandling().authenticationEntryPoint(entryPoint); 
     http.addFilterBefore(filter, BasicAuthenticationFilter.class).authorizeRequests().anyRequest() 
       .fullyAuthenticated(); 
    } 

    @Bean 
    public WindowsAuthProviderImpl windowsAuthProviderImpl() { 
     return new WindowsAuthProviderImpl(); 
    } 

    @Bean 
    public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(final WindowsAuthProviderImpl authProvider) { 
     return new NegotiateSecurityFilterProvider(authProvider); 
    } 

    @Bean 
    public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl authProvider) { 
     return new BasicSecurityFilterProvider(authProvider); 
    } 

    @Bean 
    public SecurityFilterProviderCollection securityFilterProviderCollection(
      final NegotiateSecurityFilterProvider negotiateSecurityFilterProvider, 
      final BasicSecurityFilterProvider basicSecurityFilterProvider) { 
     return new SecurityFilterProviderCollection(new SecurityFilterProvider[] { negotiateSecurityFilterProvider, 
       basicSecurityFilterProvider }); 
    } 

    @Bean 
    public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(
      final SecurityFilterProviderCollection securityFilterProviderCollection) { 
     final NegotiateSecurityFilterEntryPoint entryPoint = new NegotiateSecurityFilterEntryPoint(); 

     entryPoint.setProvider(securityFilterProviderCollection); 

     return entryPoint; 
    } 

    @Bean 
    public NegotiateSecurityFilter negotiateSecurityFilter(
      final SecurityFilterProviderCollection securityFilterProviderCollection) { 
     final NegotiateSecurityFilter filter = new NegotiateSecurityFilter(); 

     filter.setProvider(securityFilterProviderCollection); 

     return filter; 
    } 

} 

工作正常的認證過程,但我只能在這樣的控制器讀取在當前登錄用戶名:

@RequestMapping("/") 
public @ResponseBody String index(final Principal user) { 
    return String.format("Welcome to the home page, %s!", user.getName()); 
} 

對於授權,我希望爲我在數據庫中定義的用戶分配角色,並在Active Directory中存儲其他信息(如電子郵件地址,電話號碼等)。這些信息如何自動合併?

回答

4

我創建了另一個在Waffle過濾器運行後被觸發的過濾器。它檢查奶蛋烘餅是否認證了用戶。如果是這樣,我用Waffle對象的信息創建我自己的Authentication對象。

更新

在此期間,我回到以基於登錄。但我認爲我做了這樣的:

定製UserDetails類:

@Data 
public class User implements UserDetails { 

    private static final long serialVersionUID = -302856598965676658L; 

    private String username; 

    private Set<Role> authorities; 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     return authorities; 
    } 

    @Override 
    public String getPassword() { 
     return ""; 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return true; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 

} 

定製GrantedAuthority類:

@Data 
public class Role implements GrantedAuthority { 

    private static final long serialVersionUID = -7912276892872811638L; 

    private String authority; 

    @Override 
    public String getAuthority() { 
     return authority; 
    } 

} 

自定義驗證類:

public class CustomAuthentication implements Authentication { 

    private static final long serialVersionUID = -1723253799961522167L; 

    private User user; 

    public CustomAuthentication(final User user) { 
     this.user = user; 
    } 

    @Override 
    public String getName() { 
     return user.getUsername(); 
    } 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     return user.getAuthorities(); 
    } 

    @Override 
    public Object getCredentials() { 
     return null; 
    } 

    @Override 
    public Object getDetails() { 
     return null; 
    } 

    @Override 
    public Object getPrincipal() { 
     return user; 
    } 

    @Override 
    public boolean isAuthenticated() { 
     return user != null; 
    } 

    @Override 
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { 
    } 

} 

的定製過濾器:

@Component 
public class CustomFilter extends GenericFilterBean { 

    @Autowired 
    private UserService userService; 

    @Override 
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) 
      throws IOException, ServletException { 
     final SecurityContext securityContext = SecurityContextHolder.getContext(); 
     final Authentication authentication = securityContext.getAuthentication(); 

     if (authentication != null) { 
      final String username = authentication.getName(); 
      final User user = userService.getUserByUsername(username); 
      final CustomAuthentication customAuthentication = new CustomAuthentication(user); 

      securityContext.setAuthentication(customAuthentication); 
     } 

     chain.doFilter(request, response); 
    } 

} 

過濾器的註冊:

@Configuration 
@EnableWebMvcSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private NegotiateSecurityFilter waffleFilter; 

    @Autowired 
    private CustomFilter customFilter; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.addFilterBefore(waffleFilter, BasicAuthenticationFilter.class); 
     http.addFilterAfter(customFilter, NegotiateSecurityFilter.class); 
    } 

} 
+0

你有你的解決方案的代碼的例子嗎? – dataCore 2015-09-24 09:08:38

+1

@dataCore我更新了我的答案。請注意,我沒有測試代碼。 – stevecross 2015-09-24 19:38:38

+0

@SteffenKreutz - 謝謝你的回答。你能幫助我解決更多的挑戰嗎?我想驗證和授權(檢入數據庫)一些端點,但只驗證其他端點。有沒有辦法? – JHS 2016-09-02 18:59:35

相關問題