【问题标题】:How to get detailed information of users authenticated with Waffle?如何获取通过 Waffle 进行身份验证的用户的详细信息?
【发布时间】:2015-02-24 08:49:33
【问题描述】:

我正在使用 Spring Security 和 Waffle 来验证我的 web 应用程序的用户。我使用以下配置配置了 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 中。这些信息如何自动合并?

【问题讨论】:

    标签: spring spring-security waffle


    【解决方案1】:

    我创建了另一个在 Waffle 过滤器运行后触发的过滤器。它检查 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);
        }
    
    }
    

    【讨论】:

    • @dataCore 我更新了我的答案。请注意,我没有测试代码。
    • @SteffenKreutz - 谢谢你的回答。你能帮我再挑战一个吗?我想对一些端点进行身份验证和授权(检查数据库),但只对其他端点进行身份验证。有办法吗?
    • @JHS 请针对该主题提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 2019-01-27
    • 2012-09-15
    • 1970-01-01
    相关资源
    最近更新 更多