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')">