簡體   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