如何获取Waffle认证用户的详细信息?
How to get detailed information of users authenticated with Waffle?
我正在结合使用 Spring 安全和 Waffle 来验证我的网络应用程序的用户。我使用以下配置配置了 Spring 安全性:
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());
}
对于授权,我想为我在数据库中定义的用户分配角色,并且附加信息(如电子邮件地址、phone 号码等)存储在 Active Directory 中。这些信息如何自动合并?
我创建了另一个在 Waffle 过滤器 运行 之后触发的过滤器。它检查 Waffle 是否对用户进行了身份验证。如果是这样,我将使用 Waffle 对象中的信息创建自己的 Authentication
对象。
更新
与此同时,我又回到了基于表单的登录。但我想我是这样做的:
自定义 UserDetails
class:
@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
class:
@Data
public class Role implements GrantedAuthority {
private static final long serialVersionUID = -7912276892872811638L;
private String authority;
@Override
public String getAuthority() {
return authority;
}
}
自定义认证class:
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);
}
}
我正在结合使用 Spring 安全和 Waffle 来验证我的网络应用程序的用户。我使用以下配置配置了 Spring 安全性:
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());
}
对于授权,我想为我在数据库中定义的用户分配角色,并且附加信息(如电子邮件地址、phone 号码等)存储在 Active Directory 中。这些信息如何自动合并?
我创建了另一个在 Waffle 过滤器 运行 之后触发的过滤器。它检查 Waffle 是否对用户进行了身份验证。如果是这样,我将使用 Waffle 对象中的信息创建自己的 Authentication
对象。
更新
与此同时,我又回到了基于表单的登录。但我想我是这样做的:
自定义 UserDetails
class:
@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
class:
@Data
public class Role implements GrantedAuthority {
private static final long serialVersionUID = -7912276892872811638L;
private String authority;
@Override
public String getAuthority() {
return authority;
}
}
自定义认证class:
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);
}
}