使用HTTP标头的Spring Security

时间:2017-05-22 10:54:42

标签: security authentication spring-boot spring-security http-headers

我正在尝试为Spring Boot应用程序添加安全性。我当前的应用程序正在使用REST控制器,每次收到GETPOST请求时,我都会读取HTTP标头以检索用户和密码,以便根据属性文件验证它们我拥有所有用户存储。我想将其更改为使用Spring Security,这是我到目前为止所做的:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/index.html").permitAll()
            .antMatchers("/swagger-ui.html").hasRole("ADMIN")
            .anyRequest().authenticated();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("admin").password("password").roles("ADMIN").build());
    }
}

如何告诉configure方法从标题而不是登录表单中检索用户凭据?

4 个答案:

答案 0 :(得分:3)

您应该避免使用默认org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter,因为它从您的请求参数中获取客户端提供的用户名和密码,而您确实需要从标头中获取它们。

因此,您应该编写一个自定义AuthenticationFilter扩展引用UsernamePasswordAuthenticationFilter来更改其行为以符合您的要求:

public class HeaderUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    /**
     * 
     */
    public HeaderUsernamePasswordAuthenticationFilter() {
        super();
        this.setFilterProcessesUrl("/**");
        this.setPostOnly(false);
    }

    /* (non-Javadoc)
     * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#obtainPassword(javax.servlet.http.HttpServletRequest)
     */
    @Override
    protected String obtainPassword(HttpServletRequest request) {
        return request.getHeader(this.getPasswordParameter());
    }

    /* (non-Javadoc)
     * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#obtainUsername(javax.servlet.http.HttpServletRequest)
     */
    @Override
    protected String obtainUsername(HttpServletRequest request) {
        return request.getHeader(this.getPasswordParameter());
    }   

}

此过滤器示例扩展org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter侦听每个请求,并从标头而不是username获取passwordparameters

然后您应该以这种方式更改配置,将过滤器设置为UsernamePasswordAuthenticationFilter位置:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAt(
                new HeaderUsernamePasswordAuthenticationFilter(), 
                UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/index.html").permitAll()
            .antMatchers("/swagger-ui.html").hasRole("ADMIN")
            .anyRequest().authenticated();
    }

答案 1 :(得分:2)

在内存中,身份验证可以满足您的需求

@Configuration
@EnableWebMvc
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("user1").password("password1").roles("USER")
        .and()
        .withUser("user2").password("password2").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().fullyAuthenticated();
        http.httpBasic();   
    }

}

答案 2 :(得分:0)

最少的代码添加是定义一个过滤器,并将其添加到安全配置中,例如:

XHeaderAuthenticationFilter.java

@Component
public class XHeaderAuthenticationFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    String xAuth = request.getHeader("X-Authorization");

    User user = findByToken(xAuth);

    if (user == null) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token invalid");
    } else {
        final UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);

        filterChain.doFilter(request, response);
    }
}

//need to implement db user validation...
private User findByToken(String token) {
    if (!token.equals("1234"))
        return null;

    final User user = new User(
            "username",
            "password",
            true,
            true,
            true,
            true,
            Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));

    return user;
}
}

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .csrf().disable()
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
            .and()
            .addFilterBefore(new XHeaderAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

另一种方法是在输入带注释的控制器方法之前,使用spring的AOP定义要执行的某些逻辑的注释

答案 3 :(得分:-1)

在spring boot app中,您可以在下面添加到application.properties

if(isset($_POST['keywords']) && !isset($_POST['location']) && !isset($_POST['industry'])){}
elseif(isset($_POST['keywords']) && !isset($_POST['location']) && isset($_POST['industry'])){}
elseif(isset($_POST['keywords']) && isset($_POST['location']) && !isset($_POST['industry'])){}
elseif(isset($_POST['keywords']) && isset($_POST['location']) && isset($_POST['industry'])){}
elseif(!isset($_POST['keywords']) && !isset($_POST['location']) && isset($_POST['industry'])){}
elseif(!isset($_POST['keywords']) && isset($_POST['location']) && !isset($_POST['industry'])){}
elseif(!isset($_POST['keywords']) && isset($_POST['location']) && isset($_POST['industry'])){}

它将完成从标题和验证中获取它的其余部分 更多访问https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html