我有两种不同类型的用户。
SSO用户已经过不同系统的身份验证,数据库用户应该通过我们的系统进行身份验证。我可以配置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;
}
}
控件进入My Custom过滤器然后抛出异常但是没有调用ExceptionTranslationFilter
我是否正确配置了httpsecurity 我是否正确配置了自定义过滤器 我配置了ExceptionTranslation Filter 我错过了什么
答案 0 :(得分:1)
这是一个非常标准的弹簧安全用例。在遇到任何安全拦截器之前,您需要在安全上下文中提供Authentication对象。
通常,您会使用某种过滤器从请求中提取SSO参数,根据SSO服务对这些参数进行身份验证,然后创建Authentication对象并将其放入安全上下文中。过滤器的类型和过滤器的配置取决于您使用的SSO技术。
通常还会有一个过滤器(通常是ExceptionTranslationFilter),它会将未经身份验证的请求发送到登录页面。
还有一些过滤器可以从登录表单接收参数并将它们存储在安全上下文中。
总而言之,我希望有一个可能的工作流程:
用户使用SSO参数登录
用户登录时没有SSO参数(需要登录页面)
用户使用填写的登录表单登录(例如,用于DB登录)