繁体   English   中英

Spring安全性:处理SSO和DB用户

[英]Spring security : handling SSO and DB users

我有两种不同类型的用户。

  1. SSO用户
  2. 数据库用户。

SSO用户将已经由其他系统认证,而DB用户应由我们的系统认证。 我可以配置Spring安全性来处理这种情况吗?在这种情况下,我可以说某些用户的提示登录页面,而不提示某些用户。

可以说,对于SSO用户,当他们访问应用程序时,我可以在请求标头中获得用户ID,而在DB访问应用程序时,在请求标头中不存在用户ID。如何处理这种情况?

我可以通过扩展它来覆盖DaoAuthenticationProvider的身份验证方法,然后在某个参数上的页面决定对用户进行身份验证吗,或者还有其他方法吗? 我可以向身份验证类添加任何信息吗

这就是我试图做到的

安全配置Java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {
        builder.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username,password, enabled from users where username=?")
                .authoritiesByUsernameQuery("select username, role from user_roles where username=?");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic()
        .and().addFilterBefore(new UserTypeFilter(), BasicAuthenticationFilter.class);
    }

    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    /*
     * @Bean public MethodSecurityInterceptor methodSecurityService() { return
     * new MethodSecurityInterceptor(); }
     */

     @Bean(name="myAuthenticationManager")
       public AuthenticationManager authenticationManagerBean() throws Exception {
           return super.authenticationManagerBean();
       }

     @Bean
        public ExceptionTranslationFilter exceptionTranslationFilter() {
            ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(
                    new Http403ForbiddenEntryPoint());
            AccessDeniedHandlerImpl accessDeniedHandlerImpl = new AccessDeniedHandlerImpl();
            accessDeniedHandlerImpl.setErrorPage("/exception");
            exceptionTranslationFilter
                    .setAccessDeniedHandler(accessDeniedHandlerImpl);
            exceptionTranslationFilter.afterPropertiesSet();
            return exceptionTranslationFilter;
        }

     @Bean
     public UserTypeFilter authenticationFilter() throws Exception {
         UserTypeFilter authFilter = new UserTypeFilter();
         authFilter.setAuthenticationManager(authenticationManager());
         return authFilter;
     }
}

我的自定义AbstractAuthenticationProcessingFilter

public class UserTypeFilter extends AbstractAuthenticationProcessingFilter {

    private static final String INTERCEPTOR_PROCESS_URL = "/index";

    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

    public UserTypeFilter() {
        super(INTERCEPTOR_PROCESS_URL);
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        System.out.println(" BASIC AUTHENTICATION FILTER");
        String userId = request.getHeader("USERID");
        if (userId == null) {
            System.out.println(" THROWING EXCEPTION FILTER");
            throw new PreAuthenticatedCredentialsNotFoundException("USERID param not found");
        }
        return null;
    }

}

我的控制器

@Controller
public class MainController {


    @RequestMapping(value = { "/index" }, method = RequestMethod.GET)
    public ModelAndView index() {

        ModelAndView model = new ModelAndView();
        model.addObject("message", "This is test page!");
        model.setViewName("dummy");

        return model;

    }

}

控件转到“我的自定义”过滤器,然后在引发异常但未调用ExceptionTranslationFilter时

我是否已正确配置httpsecurity我是否已正确配置我的自定义过滤器我是否已配置ExceptionTranslation过滤器我是否缺少任何内容

这是用于弹簧安全性的相当标准的用例。 在遇到任何安全拦截器之前,您需要在安全上下文中提供一个Authentication对象。

通常,您将具有某种过滤器,该过滤器从请求中提取SSO参数,针对SSO服务对这些参数进行身份验证,然后创建一个Authentication对象并将其放入安全上下文中。 过滤器的类型和过滤器的配置将取决于您使用的SSO技术。

通常还会有一个过滤器(通常是ExceptionTranslationFilter),该过滤器会将未经身份验证的请求发送到登录页面。

也将有过滤器从登录表单接收参数并将其存储在安全上下文中。

放在一起,我希望一种可能的工作流程是:

用户使用SSO参数登录

  1. 请求中预先填充了凭据
  2. 一些过滤器提取那些凭据,对其进行验证,创建Authentication对象,然后将该对象放置在安全上下文中。
  3. 安全拦截器在安全上下文中找到Authentication对象,验证是否允许用户访问特定功能,并将请求继续传递。

用户无需SSO参数即可登录(需要登录页面)

  1. 请求没有凭据
  2. 安全拦截器未找到任何身份验证对象,并引发异常。
  3. ExceptionTranslationFilter将异常转换为重定向到登录页面。

用户使用填写的登录表单登录(例如,用于数据库登录)

  1. 请求带有登录表单作为实体主体
  2. 某些过滤器(例如UsernamePasswordAuthenticationFilter)从登录表单中提取凭据,并转交给身份验证提供程序(例如您的DAO身份验证提供程序)以查询数据库并验证用户。 如果验证通过,此过滤器将创建一个Authentication对象,并将其放置在安全上下文中。
  3. 安全拦截器在安全上下文中找到Authentication对象,验证是否允许用户访问特定功能,并将请求继续传递。

暂无
暂无

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

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