JSP & Spring 安全:重定向工作正常,但没有登录
JSP & Spring Security: redirect is working correct, but without login
我正在为 Spring 引导项目实施 Spring 安全性。
问题是:如果我使用 Spring 安全配置,例如:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public SecurityConfiguration(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(bCryptPasswordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().
antMatchers("/index", "/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").failureUrl("/error")
.defaultSuccessUrl("/CarRentalServlet", true)
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
控制器的逻辑是:
@Controller
public class CarRentalController {
final OrderRepository orderRepository;
final VehicleRepository vehicleRepository;
private final CommandFactory commandFactory;
public CarRentalController(OrderRepository orderRepository, VehicleRepository vehicleRepository, CommandFactory commandFactory) {
this.orderRepository = orderRepository;
this.vehicleRepository = vehicleRepository;
this.commandFactory = commandFactory;
}
@GetMapping("/{view}")
public String viewMapping(@PathVariable String view) {
return view;
}
@RequestMapping(value = { "/CarRentalServlet" }, method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView getCommand(@RequestParam(required = false) String command,
HttpServletRequest req, HttpServletResponse res,
HttpSession session,
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page
) throws ServletException, IOException {
Page<Vehicle> vehiclePage = vehicleRepository.findAll(new PageRequest(page, 2, new Sort(Sort.Direction.DESC, "dailyPrice")));
session.setAttribute("number", vehiclePage.getNumber());
session.setAttribute("totalPages", vehiclePage.getTotalPages());
session.setAttribute("totalElements", vehiclePage.getTotalElements());
session.setAttribute("size", vehiclePage.getSize());
session.setAttribute("data",vehiclePage.getContent());
session.setAttribute("orderList", orderRepository.findAll());
session.setAttribute("vehicleList", vehicleRepository.findAll());
return commandFactory.getCommand(command).execute(req, res, session);
}
}
和login.jspx
文件为jsp形式:
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><fmt:message key="login.paneltitle" /></h3>
</div>
<div class="panel-body">
<form role="form" name="loginForm" method="POST" action="${pageContext.request.contextPath}/login">
<input type="hidden" name="command" value="logInCommand"/>
<fieldset>
<div class="form-group">
<fmt:message key="login.label.login" var="loginValue" />
<input class="form-control" placeholder="${loginValue}" name="username" type="text" autofocus=""/>
</div>
<div class="form-group">
<fmt:message key="login.label.password" var="passwordValue" />
<input class="form-control" placeholder="${passwordValue}" name="password" type="password" value=""/>
</div>
<fmt:message key="login.button.login" var="loginButtonValue" />
<input type="submit" class="btn btn-lg btn-success btn-block" value="${loginButtonValue}" />
</fieldset>
</form>
</div>
</div>
</div>
另一种jsp形式为index.jsp
:
<div class="navbar-default navbar-static-side" role="navigation">
<div class="sidebar-collapse">
<ul class="nav" id="side-menu">
<c:if test="${!empty sessionScope.userName}">
<li>
<form name="makeOrderButton" method="post" action="CarRentalServlet">
<input type="hidden" name="command" value="makeOrderButtonCommand"/>
<a href="" onclick="parentNode.submit();
return false;">
<i class="fa fa-shopping-cart fa-fw"></i>
<fmt:message key="index.button.makeOrder" />
</a>
</form>
</li>
<c:if test="${sessionScope.userTypeID == 1}">
<li>
<form name="adminZoneButton" method="post" action="CarRentalServlet">
<input type="hidden" name="command" value="adminZoneButtonCommand"/>
<a href="" onclick="parentNode.submit();
return false;">
<i class="fa fa-wrench fa-fw"></i>
<fmt:message key="index.button.adminZone" />
</a>
</form>
</li>
</c:if>
</c:if>
</ul>
<!-- /#side-menu -->
</div>
<!-- /.sidebar-collapse -->
</div>
它将我重定向到正确的端点 /CarRentalServlet
,但登录根本不起作用。
例如,如果我不使用 SecurityConfiguration
class,但我会修改我的 jsp 文件,如:
action="CarRentalServlet"
而不是 action="${pageContext.request.contextPath}/login"
和 name="login"
而不是 name="username"
它按预期工作并且登录正常,但在这种情况下我不使用 Spring 安全性。
有人可以建议我如何修复 Spring 安全配置或 JSP 表单以使登录在没有 Spring 安全的情况下正常工作。
问题是因为在 jsp 个文件中使用了 <c:if test="${!empty sessionScope.userName}">
和 <c:if test="${sessionScope.userTypeID == 1}">
。
为了修复它,我使用了 authorize tag。所以我相应地更改为 <sec:authorize access="isAuthenticated()">
和 <sec:authorize access="hasRole('ADMIN')">
。
我正在为 Spring 引导项目实施 Spring 安全性。
问题是:如果我使用 Spring 安全配置,例如:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public SecurityConfiguration(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(bCryptPasswordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().
antMatchers("/index", "/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").failureUrl("/error")
.defaultSuccessUrl("/CarRentalServlet", true)
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
控制器的逻辑是:
@Controller
public class CarRentalController {
final OrderRepository orderRepository;
final VehicleRepository vehicleRepository;
private final CommandFactory commandFactory;
public CarRentalController(OrderRepository orderRepository, VehicleRepository vehicleRepository, CommandFactory commandFactory) {
this.orderRepository = orderRepository;
this.vehicleRepository = vehicleRepository;
this.commandFactory = commandFactory;
}
@GetMapping("/{view}")
public String viewMapping(@PathVariable String view) {
return view;
}
@RequestMapping(value = { "/CarRentalServlet" }, method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView getCommand(@RequestParam(required = false) String command,
HttpServletRequest req, HttpServletResponse res,
HttpSession session,
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page
) throws ServletException, IOException {
Page<Vehicle> vehiclePage = vehicleRepository.findAll(new PageRequest(page, 2, new Sort(Sort.Direction.DESC, "dailyPrice")));
session.setAttribute("number", vehiclePage.getNumber());
session.setAttribute("totalPages", vehiclePage.getTotalPages());
session.setAttribute("totalElements", vehiclePage.getTotalElements());
session.setAttribute("size", vehiclePage.getSize());
session.setAttribute("data",vehiclePage.getContent());
session.setAttribute("orderList", orderRepository.findAll());
session.setAttribute("vehicleList", vehicleRepository.findAll());
return commandFactory.getCommand(command).execute(req, res, session);
}
}
和login.jspx
文件为jsp形式:
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><fmt:message key="login.paneltitle" /></h3>
</div>
<div class="panel-body">
<form role="form" name="loginForm" method="POST" action="${pageContext.request.contextPath}/login">
<input type="hidden" name="command" value="logInCommand"/>
<fieldset>
<div class="form-group">
<fmt:message key="login.label.login" var="loginValue" />
<input class="form-control" placeholder="${loginValue}" name="username" type="text" autofocus=""/>
</div>
<div class="form-group">
<fmt:message key="login.label.password" var="passwordValue" />
<input class="form-control" placeholder="${passwordValue}" name="password" type="password" value=""/>
</div>
<fmt:message key="login.button.login" var="loginButtonValue" />
<input type="submit" class="btn btn-lg btn-success btn-block" value="${loginButtonValue}" />
</fieldset>
</form>
</div>
</div>
</div>
另一种jsp形式为index.jsp
:
<div class="navbar-default navbar-static-side" role="navigation">
<div class="sidebar-collapse">
<ul class="nav" id="side-menu">
<c:if test="${!empty sessionScope.userName}">
<li>
<form name="makeOrderButton" method="post" action="CarRentalServlet">
<input type="hidden" name="command" value="makeOrderButtonCommand"/>
<a href="" onclick="parentNode.submit();
return false;">
<i class="fa fa-shopping-cart fa-fw"></i>
<fmt:message key="index.button.makeOrder" />
</a>
</form>
</li>
<c:if test="${sessionScope.userTypeID == 1}">
<li>
<form name="adminZoneButton" method="post" action="CarRentalServlet">
<input type="hidden" name="command" value="adminZoneButtonCommand"/>
<a href="" onclick="parentNode.submit();
return false;">
<i class="fa fa-wrench fa-fw"></i>
<fmt:message key="index.button.adminZone" />
</a>
</form>
</li>
</c:if>
</c:if>
</ul>
<!-- /#side-menu -->
</div>
<!-- /.sidebar-collapse -->
</div>
它将我重定向到正确的端点 /CarRentalServlet
,但登录根本不起作用。
例如,如果我不使用 SecurityConfiguration
class,但我会修改我的 jsp 文件,如:
action="CarRentalServlet"
而不是 action="${pageContext.request.contextPath}/login"
和 name="login"
而不是 name="username"
它按预期工作并且登录正常,但在这种情况下我不使用 Spring 安全性。
有人可以建议我如何修复 Spring 安全配置或 JSP 表单以使登录在没有 Spring 安全的情况下正常工作。
问题是因为在 jsp 个文件中使用了 <c:if test="${!empty sessionScope.userName}">
和 <c:if test="${sessionScope.userTypeID == 1}">
。
为了修复它,我使用了 authorize tag。所以我相应地更改为 <sec:authorize access="isAuthenticated()">
和 <sec:authorize access="hasRole('ADMIN')">
。