我需要更新我的Spring Security配置,引入多租户管理(每个web请求都有一个URL,并通过配置文件检索正确的模式)。
因此,我在Spring Security配置中添加了一个过滤器(因为使用处理程序时,登录页面没有正确的模式,因为处理程序在Spring Security之后调用),但现在我捕获URL,设置模式,但页面仍然为空,不会重定向到登录页面,如果我写/login,也没有HTML页面出现。
这是我如何配置Spring Security的方式:
但是当我编写登录页面的控制器时,它没有接收到调用:
这是我如何配置Spring Security的方式:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private RoleServices roleServices;
@Autowired
private CustomSuccessHandler customSuccessHandler;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth)throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username,password,enabled from user where username=?")
.authoritiesByUsernameQuery("select u.username, CONCAT('ROLE_' , r.role) from user u inner join role r on u.idRole = r.idRole where lower(u.username) = lower(?)");
}
@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Override
public void configure(WebSecurity web) throws Exception {
web
//Spring Security ignores request to static resources such as CSS or JS files.
.ignoring()
.antMatchers("/static/**","/users/{\\d+}/password/recover","/users/{\\d+}/token/{\\d+}/password/temporary")
.antMatchers(HttpMethod.PUT,"/users/{\\d+}/token/{\\d+}/password/temporary");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
List<Role> roles=roleServices.getRoles();
//Retrieve array of roles(only string field without id)
String[] rolesArray = new String[roles.size()];
int i=0;
for (Role role:roles){
rolesArray[i++] = role.getRole();
}
http
.authorizeRequests() //Authorize Request Configuration
.anyRequest().hasAnyRole(rolesArray)//.authenticated()
.and()//Login Form configuration for all others
.formLogin()
.loginPage("/login").successHandler(customSuccessHandler)
//important because otherwise it goes in a loop because login page require authentication and authentication require login page
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID", "JSESSIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.sessionManagement().invalidSessionUrl("/login")
.and()
.addFilterAfter(new MultiTenancyInterceptor(), BasicAuthenticationFilter.class);
}
}
我添加了MultiTenancyInterceptor
过滤器,其中我设置了租户。
@Component
public class MultiTenancyInterceptor extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
String url = request.getRequestURL().toString();
URI uri;
try {
uri = new URI(url);
String domain = uri.getHost();
if(domain!=null){
TenantContext.setCurrentTenant(domain);
}
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
但是当我编写登录页面的控制器时,它没有接收到调用:
@Override
@RequestMapping(value = { "/login" }, method = RequestMethod.GET)
public String loginPage(){
return "login";
}
你看到我configure
方法中的错误了吗?如果需要更多信息,我可以添加其他类。谢谢。
PS:我注意到每个页面请求doFilter
被调用了两次。