Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于选择的AuthProvider Spring安全性_Java_Spring_Spring Security - Fatal编程技术网

Java 基于选择的AuthProvider Spring安全性

Java 基于选择的AuthProvider Spring安全性,java,spring,spring-security,Java,Spring,Spring Security,我已经将Spring安全性配置为同时使用LDAP和基于DB的登录。首先,它尝试通过LDAP登录,如果所需的权限不存在,则转到用户名/密码输入页面 <security:http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint"> <security:custom-filter ref="customPreAuthFilter" position="PRE_AUTH_FILTER"/

我已经将Spring安全性配置为同时使用LDAP和基于DB的登录。首先,它尝试通过LDAP登录,如果所需的权限不存在,则转到用户名/密码输入页面

<security:http auto-config="false" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <security:custom-filter ref="customPreAuthFilter" position="PRE_AUTH_FILTER"/> // This is for LDAP
    <security:custom-filter ref="customAuthFilter" position="FORM_LOGIN_FILTER"/> // This is for DB Based

    /** intercept urls 

    **/

</security:http>
我想在顶部添加一个新屏幕,用户需要在两个按钮LDAP或username/pass之间进行选择。我该如何进行

要访问的数据是相同的url,即/home,但ldap和DB用户都应该能够访问。

如果查看UsernamePasswordAuthenticationFilter中的代码,则有setDetails方法

发件人:

提供,以便子类可以配置放入 身份验证请求的详细信息属性

从这里开始的想法

您可以在此处设置authtype之类的详细信息,并使用it身份验证提供程序,但要实现您想要的功能,只需做很少的工作

增加细节,希望能有所帮助

CustomUsernamePasswordAuthenticationFilter.java

CustomWebAuthenticationDetailsSource.java

请注意这些课程仅供演示之用

需要自动连接这些类中的实际身份验证提供程序

import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.stereotype.Component;

@Component
public class AuthenicationProviderJdbcLdapImpl implements AuthenticationProvider{

    // you need to autowire jdbc auth provider
    @Autowired(required = false)
    DaoAuthenticationProvider authenticationProvider;

    //you need to autowire ldap auth provider
    @Autowired(required = false)
    LdapAuthenticationProvider ldapAuthenticationProvider;



    protected static class User{
        private final String userId;
        private final String password;
        public User(String userId,String password) {
            this.userId = userId;
            this.password = password;
        }
        public String getUserId() {
            return userId;
        }
        public String getPassword() {
            return password;
        }
        @Override
        public String toString() {
            return "User [userId=" + userId + ", password=" + password + "]";
        }
    }

    private final static Logger logger = LoggerFactory.getLogger(AuthenicationProviderJdbcLdapImpl.class);
    private static final List<User> users1 = Arrays.asList(new User("admin1", "password"),new User("admin2", "password"));
    private static final List<User> users2 = Arrays.asList(new User("admin3", "password"),new User("admin4", "password"));

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        CustomAuthenticationDetails details = (CustomAuthenticationDetails) authentication.getDetails();

        String authType = details.getAuthType();
        logger.info("authType {}",authType);
        if("jdbc".equalsIgnoreCase(authType)) {
            logger.info("perfrom jdbc authentication");

            //perform your authentication using jdbc
            //the below is just for explaination

            return performAuthentication(authentication, users1);

        }else if("ldap".equalsIgnoreCase(authType)) {
            logger.info("perfrom ldap authentication");

            //perform your authentication using ldap
            //the below is just for explaination

            return performAuthentication(authentication, users2);

        }
        return null;
    }

    private Authentication performAuthentication(Authentication authentication,List<User> users) {
        String credential =  (String) authentication.getCredentials();
        String userId = authentication.getName();
        for(User user: users) {
            if(user.getUserId().equals(userId)&& user.getPassword().equals(credential)) {
                authentication = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(),authentication.getAuthorities());

                return authentication;
            }
        }
        return null;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }



}
WebSecurityConfig.java

下面是authType=jdbc或authType=ldap时的日志


您的过滤器实现是什么样子的?我想知道您是否正在检查要在筛选器中执行哪种身份验证,以及如果身份验证失败,您会怎么做?您是否看到任何错误?如xml中所示,有两个筛选器。第一个是提取用于LDAP检查的头值。第二个是使用过滤器传递第三个值,即验证码。之后,在这两种情况下,getAuthenticationManager.authenticateauthentication;被称为。筛选器不会执行额外操作,而不会将控制权传递给身份验证管理器。这将允许用户在不进行身份验证的情况下进入该页面。是否要根据用户选择更改spring安全配置!?我认为您将无法动态更改配置,但这似乎是一种方法:1。新屏幕2的屏幕高度。设置由您指定的会话标志3。检查该标志并相应地调整过滤器。另一种方法是:编辑答案,根据输入选择验证提供程序,并根据条件重定向到不同的登录页面,如果这是您的原始问题,如果我在创建WebAuthenticationDetails时未找到线程绑定请求怎么办?将其标记为@Component,以便在自定义筛选时找到beancreating@user2501323这是一个问题还是澄清?@Haider不。如果你理解这个概念,我认为你应该能够实现它。
public class CustomAuthenticationDetails extends WebAuthenticationDetails{


    private  final String authType;

    public CustomAuthenticationDetails(HttpServletRequest request) {
        super(request);
        authType = request.getParameter("authType");
    }

    public String getAuthType() {
        return authType;
    }
}
public class CustomWebAuthenticationDetailsSource extends WebAuthenticationDetailsSource {

    @Override
    public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
        return new CustomAuthenticationDetails(context);
    }

}
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.stereotype.Component;

@Component
public class AuthenicationProviderJdbcLdapImpl implements AuthenticationProvider{

    // you need to autowire jdbc auth provider
    @Autowired(required = false)
    DaoAuthenticationProvider authenticationProvider;

    //you need to autowire ldap auth provider
    @Autowired(required = false)
    LdapAuthenticationProvider ldapAuthenticationProvider;



    protected static class User{
        private final String userId;
        private final String password;
        public User(String userId,String password) {
            this.userId = userId;
            this.password = password;
        }
        public String getUserId() {
            return userId;
        }
        public String getPassword() {
            return password;
        }
        @Override
        public String toString() {
            return "User [userId=" + userId + ", password=" + password + "]";
        }
    }

    private final static Logger logger = LoggerFactory.getLogger(AuthenicationProviderJdbcLdapImpl.class);
    private static final List<User> users1 = Arrays.asList(new User("admin1", "password"),new User("admin2", "password"));
    private static final List<User> users2 = Arrays.asList(new User("admin3", "password"),new User("admin4", "password"));

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        CustomAuthenticationDetails details = (CustomAuthenticationDetails) authentication.getDetails();

        String authType = details.getAuthType();
        logger.info("authType {}",authType);
        if("jdbc".equalsIgnoreCase(authType)) {
            logger.info("perfrom jdbc authentication");

            //perform your authentication using jdbc
            //the below is just for explaination

            return performAuthentication(authentication, users1);

        }else if("ldap".equalsIgnoreCase(authType)) {
            logger.info("perfrom ldap authentication");

            //perform your authentication using ldap
            //the below is just for explaination

            return performAuthentication(authentication, users2);

        }
        return null;
    }

    private Authentication performAuthentication(Authentication authentication,List<User> users) {
        String credential =  (String) authentication.getCredentials();
        String userId = authentication.getName();
        for(User user: users) {
            if(user.getUserId().equals(userId)&& user.getPassword().equals(credential)) {
                authentication = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(),authentication.getAuthorities());

                return authentication;
            }
        }
        return null;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }



}
http.failureHandler(new AuthenticationFailureHandler() {

                        @Override
                        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                AuthenticationException exception) throws IOException, ServletException {
                            String whichPage = request.getParameter("whichPage");
                            System.out.println("inside login failure handler "+whichPage);
                            if("login1".equals(whichPage)) {
                                response.sendRedirect(request.getContextPath() +"/login1");
                            }else {
                                response.sendRedirect(request.getContextPath() +"/login");
                            }
                        }
                    })
import java.io.IOException;


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

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.authentication.AuthenticationManager;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager getAuthenticationManager() throws Exception {
        return super.authenticationManagerBean();
    }


    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired()
    AuthenicationProviderJdbcImpl authenicationProviderJdbcImpl;

    @Autowired()
    AuthenicationProviderLdapImpl authenicationProviderLdapImpl;


    @Autowired
    CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAt(customUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        http
                .authorizeRequests()
                    .antMatchers("/resources/**", "/registration","/login1").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()//.successHandler(authenticationSuccessHandler)
                    .failureHandler(new AuthenticationFailureHandler() {

                        @Override
                        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                AuthenticationException exception) throws IOException, ServletException {
                            String whichPage = request.getParameter("whichPage");
                            System.out.println("inside login failure handler "+whichPage);
                            if("login1".equals(whichPage)) {
                                response.sendRedirect(request.getContextPath() +"/login1");
                            }else {
                                response.sendRedirect(request.getContextPath() +"/login");
                            }
                        }
                    })
                    .and()
                .logout()
                    .permitAll();
    }

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(authenicationProviderLdapImpl).authenticationProvider(authenicationProviderJdbcImpl);

    }



    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        /*auth.userDetailsService(userDetailsService)
        .passwordEncoder(bCryptPasswordEncoder());*/

    }
}
login called
2018-11-23 17:45:25.606  INFO 7232 --- [nio-8080-exec-6] stomUsernamePasswordAuthenticationFilter : authType jdbc 
2018-11-23 17:45:25.606  INFO 7232 --- [nio-8080-exec-6] c.t.a.AuthenicationProviderJdbcLdapImpl  : authType jdbc
2018-11-23 17:45:25.606  INFO 7232 --- [nio-8080-exec-6] c.t.a.AuthenicationProviderJdbcLdapImpl  : perfrom jdbc authentication
login called
login1 called
login1 called
2018-11-23 17:45:42.435  INFO 7232 --- [nio-8080-exec-5] stomUsernamePasswordAuthenticationFilter : authType ldap 
2018-11-23 17:45:42.435  INFO 7232 --- [nio-8080-exec-5] c.t.a.AuthenicationProviderJdbcLdapImpl  : authType ldap
2018-11-23 17:45:42.435  INFO 7232 --- [nio-8080-exec-5] c.t.a.AuthenicationProviderJdbcLdapImpl  : perfrom ldap authentication   returning true in ldap