配置 Spring 安全性以使用两个不同的登录页面
Configuring Spring Security To Work With Two Different Login Pages
我们可能需要两个登录页面的一种情况是,一个页面供应用程序管理员使用,另一个页面供普通用户使用。
每个http元素都会有不同的登录页面和不同的登录处理URL
我有这个 Spring 启动安全配置允许登录多个页面。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
public App1ConfigurationAdapter() {
super();
}
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Value("${admin-users-query}")
private String usersQuery;
@Value("${admin-roles-query}")
private String rolesQuery;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin*")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/admin/temp/login")
.failureUrl("//admin/temp?error=loginError")
.defaultSuccessUrl("/")
.usernameParameter("email")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/admin/temp/logout")
.logoutSuccessUrl("/admin/temp")
.and()
.exceptionHandling()
.accessDeniedPage("/403").and().csrf();
}
}
@Configuration
@Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Value("${user-users-query}")
private String usersQuery;
@Value("${user-roles-query}")
private String rolesQuery;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user*")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/user/temp/login")
.failureUrl("/user/temp/?error=loginError")
.defaultSuccessUrl("/user/temp")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/user/temp/logout")
.logoutSuccessUrl("/user/temp/login")
.and()
.exceptionHandling()enter code here
.accessDeniedPage("/403").and().csrf();
}
}
@Configuration
@Order(3)
public static class guestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring().antMatchers("/js/**", "/js/***", "/js/****");
}
}
管理员登录表单/admin/temp/login
<form th:action="@{/admin/temp/login}" method="post">
<div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-envelope"></i></span>
<input type="text" class="form-control" placeholder="Email" name="email" data-validation="required" />
</div>
<div class="input-group mb-4">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" placeholder="Password" name="password" data-validation="required" />
</div>
<div class="row">
<div class="col-6">
<input type="submit" class="btn btn-primary px-4" value="Login">
</div>
<div class="col-6 text-right">
<a href="#" class="btn btn-link px-0">Forgot password?</a>
</div>
</div>
</form>
用户登录表单/user/temp/login
<form th:action="@{/user/temp/login}" method="post">
<div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-envelope"></i></span>
<input type="text" class="form-control" placeholder="Email" name="username" data-validation="required" />
</div>
<div class="input-group mb-4">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" placeholder="Password" name="password" data-validation="required" />
</div>
<div class="row">
<div class="col-6">
<input type="submit" class="btn btn-primary px-4" value="Login">
</div>
<div class="col-6 text-right">
<a href="#" class="btn btn-link px-0">Forgot password?</a>
</div>
</div>
</form>
当我提交表格时,我得到
**Code: 405
(Method Not Allowed)**
When I use single form the form get submted.
Does anyone has an idea on whats happening her?
默认情况下 Spring 假定 URL 来验证凭据是 /login
。要更改它,您应该为两个 formLogin
配置设置 loginProcessingUrl
。
应该是这样的:
.formLogin()
.loginPage("/user/temp/login")
.failureUrl("/user/temp/?error=loginError")
.defaultSuccessUrl("/user/temp")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/user/temp/login") # missing line
因为有人已经回答你需要添加
.loginPage("/login.html")
.loginProcessingUrl("/admin/temp/login")
默认 URL Spring 登录将 POST 触发身份验证过程的默认值是 /login,在 Spring 之前是 /j_spring_security_check安全 4.
我们可能需要两个登录页面的一种情况是,一个页面供应用程序管理员使用,另一个页面供普通用户使用。 每个http元素都会有不同的登录页面和不同的登录处理URL
我有这个 Spring 启动安全配置允许登录多个页面。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
public App1ConfigurationAdapter() {
super();
}
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Value("${admin-users-query}")
private String usersQuery;
@Value("${admin-roles-query}")
private String rolesQuery;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin*")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/admin/temp/login")
.failureUrl("//admin/temp?error=loginError")
.defaultSuccessUrl("/")
.usernameParameter("email")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/admin/temp/logout")
.logoutSuccessUrl("/admin/temp")
.and()
.exceptionHandling()
.accessDeniedPage("/403").and().csrf();
}
}
@Configuration
@Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Value("${user-users-query}")
private String usersQuery;
@Value("${user-roles-query}")
private String rolesQuery;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user*")
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/user/temp/login")
.failureUrl("/user/temp/?error=loginError")
.defaultSuccessUrl("/user/temp")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/user/temp/logout")
.logoutSuccessUrl("/user/temp/login")
.and()
.exceptionHandling()enter code here
.accessDeniedPage("/403").and().csrf();
}
}
@Configuration
@Order(3)
public static class guestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring().antMatchers("/js/**", "/js/***", "/js/****");
}
}
管理员登录表单/admin/temp/login
<form th:action="@{/admin/temp/login}" method="post">
<div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-envelope"></i></span>
<input type="text" class="form-control" placeholder="Email" name="email" data-validation="required" />
</div>
<div class="input-group mb-4">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" placeholder="Password" name="password" data-validation="required" />
</div>
<div class="row">
<div class="col-6">
<input type="submit" class="btn btn-primary px-4" value="Login">
</div>
<div class="col-6 text-right">
<a href="#" class="btn btn-link px-0">Forgot password?</a>
</div>
</div>
</form>
用户登录表单/user/temp/login
<form th:action="@{/user/temp/login}" method="post">
<div class="input-group mb-3">
<span class="input-group-addon"><i class="icon-envelope"></i></span>
<input type="text" class="form-control" placeholder="Email" name="username" data-validation="required" />
</div>
<div class="input-group mb-4">
<span class="input-group-addon"><i class="icon-lock"></i></span>
<input type="password" class="form-control" placeholder="Password" name="password" data-validation="required" />
</div>
<div class="row">
<div class="col-6">
<input type="submit" class="btn btn-primary px-4" value="Login">
</div>
<div class="col-6 text-right">
<a href="#" class="btn btn-link px-0">Forgot password?</a>
</div>
</div>
</form>
当我提交表格时,我得到
**Code: 405
(Method Not Allowed)**
When I use single form the form get submted.
Does anyone has an idea on whats happening her?
默认情况下 Spring 假定 URL 来验证凭据是 /login
。要更改它,您应该为两个 formLogin
配置设置 loginProcessingUrl
。
应该是这样的:
.formLogin()
.loginPage("/user/temp/login")
.failureUrl("/user/temp/?error=loginError")
.defaultSuccessUrl("/user/temp")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/user/temp/login") # missing line
因为有人已经回答你需要添加
.loginPage("/login.html")
.loginProcessingUrl("/admin/temp/login")
默认 URL Spring 登录将 POST 触发身份验证过程的默认值是 /login,在 Spring 之前是 /j_spring_security_check安全 4.