繁体   English   中英

没有web.xml的Spring安全自定义身份验证过滤器

[英]Spring security custom authentication filter without web.xml

使用注释和java配置我不太清楚如何为spring security注册一个重写的过滤器。

我想要实现的是在不显示登录表单的情况下进行自动登录,因为此时用户已经过身份验证。 因此,只会读取标题参数并使用spring security进行授权。

这是我正在尝试的简化版本,Spring安全性正常工作,除了有时显示登录屏幕。 引导BypassLoginFilter是我需要的全部内容。 另外在某处读取http自动配置应该关闭这种行为,但不知道如何在纯java配置中实现。

SecurityWebApplicationInitializer.java

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{

}

SecurityConfig .java

import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.logout.LogoutFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");    
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().antMatchers("/*").permitAll()
                .anyRequest().hasRole("USER").and()
                .formLogin()
                .permitAll();
        http.addFilterBefore(new BypassLoginFilter(), LogoutFilter.class);
        //.and().anonymous().disable();
    }

    @Override
    @Autowired
    protected void registerAuthentication(AuthenticationManagerBuilder auth) {
        try {
            auth.inMemoryAuthentication().withUser("user").password("password")
            .roles("USER").and().withUser("admin").password("password")
            .roles("USER", "ADMIN");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

BypassLoginFilter.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

public class BypassLoginFilter extends AbstractAuthenticationProcessingFilter{

    private static String HEADER_IS_ADMIN = "isAdmin";

    public BypassLoginFilter()
    {
        super("/*");
    }

        //Never gets executed
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException,
            IOException, ServletException {

        boolean isAdmin = Boolean.valueOf(request.getHeader(HEADER_IS_ADMIN));

        PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken("","",getAuthorities(isAdmin));
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

        return getAuthenticationManager().authenticate(authRequest);
    }

    private List<GrantedAuthority> getAuthorities(boolean isAdmin)
    {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        if(isAdmin){
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        }
        return authorities;
    }
}

您可以尝试以下方法。 假设您有一个YourUser类:

public class YourUser extends org.springframework.security.core.userdetails.User{
   ...
   public String getStartPage(){ return "/userhomepage"; }
   ...
}

然后你需要声明身份验证处理程序:

@Component
public class YourAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication.getPrincipal() instanceof YourUser) {
            final YourUser user = (YourUser) authentication.getPrincipal();
            return user.getStartPage();
        }else {
            return "/defaultPageForNonAuthenticatedUsers";
        }
    }
}

并在安全配置中使用它:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // rest calls are ommited
        http.successHandler(successHandler());
    }

    @Bean
    public AuthenticationSuccessHandler successHandler() throws Exception {
        return new YourAuthenticationSuccessHandler();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM