java - 在 Spring 中使用 AuthenticationSuccessHandler 重定向登录页面

标签 java spring hibernate spring-boot spring-security

我是 Spring 和 Hibernate 的新手。我试图找到根据用户在登录时选择的选择选项在成功登录时将表单重定向到特定页面的最佳方法。我不知道这是否是最好的方法,所以请您提供建议。

这是我的解决方案,所以:

public AuthenticationSuccessHandler loginSuccessHandler() {
        //return (request, response, authentication) -> response.sendRedirect("/");
        return (request, response, authentication)-> {
            HttpSession session = request.getSession(false);
            if(session != null){
                request.setAttribute("program","program");
                if(request.getAttribute("program") != null) {
                    response.sendRedirect("/cert-prog");
                }
            }
            response.sendRedirect("/");
        };
    }

这是我用作选择选项的表单部分:

     <select class="form-control input-lg">
                    <option value="" disabled="disabled">[Select Program Type]</option>
                    <option th:each="program : ${programs}" th:value="${program.values}" th:text="${program.name}" >Certificate programs</option>
                </select>

我的登录表单:

    <form class="myform" th:action="@{/login}" th:object="${user}" method="post">
        <div class="form-group">
            <select class="form-control input-lg">
                <option value="" disabled="disabled">[Select Program Type]</option>
                <option th:each="program : ${programs}" th:value="${program.values}" th:text="${program.name}" >Certificate programs</option>
            </select>
        </div>
        <div class="form-group">
            <div class="input-group input-group-lg">
                <span class="input-group-addon" id="sizing-addon1">@</span>
                <input type="text" class="form-control" placeholder="LoginID" th:field="*{username}" aria-describedby="sizing-addon1" />
            </div>
        </div>
           <div class="form-group">
            <div class="input-group input-group-lg">
                <span class="input-group-addon form-wrapper" id="sizing-addon2">@</span>
                <input type="password" class="form-control showpassword" placeholder="Pin" th:field="*{password}"  aria-describedby="sizing-addon1"  />
                <span class="input-group-btn">
                <button class="btn btn-default toggle" type="button">Show Pin</button>
                </span>
            </div>
        </div>
        <div>
            <label>
                <input type="checkbox" value="1" id="checkbox" /> <p class="login-caution">I have carefully read all instructions as well as programme requirements in the Admission Brochure and i here my accept any responsibility for any omission(s) or error(s) on my submitted form.</p>
            </label>
        </div>
        <button type="submit" id="btnCheck" class="btn btn-primary btn-lg btn-block">Login</button>
    </form>

LoginController.java

    @Controller
    public class LoginController {

        @RequestMapping(path = "/login", method = RequestMethod.GET)
        public String loginForm(Model model, HttpServletRequest request) {
            model.addAttribute("user", new User());
           // model.addAttribute("programs", Programs.values());
            try {
                Object flash = request.getSession().getAttribute("flash");
                model.addAttribute("flash", flash);

                request.getSession().removeAttribute("flash");
            } catch (Exception ex) {
                // "flash" session attribute must not exist...do nothing and proceed normally
            }
            return "login";
        }

        @RequestMapping("/access_denied")
        public String accessDenied() {
            return "access_denied";
        }
    }

SecurityConfig.java:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private UserService userService;

        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
            auth.userDetailsService(userService);
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/assets/**");

        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                        .anyRequest().hasRole("USER")
                        .and()
                    .formLogin()
                        .loginPage("/login")
                        .permitAll()
                        .successHandler(loginSuccessHandler())
                        .failureHandler(loginFailureHandler())
                        .and()
                    .logout()
                    .permitAll()
                    .logoutSuccessUrl("/login");
        }

        //Certificate-program"
        public AuthenticationSuccessHandler loginSuccessHandler() {
            //return (request, response, authentication) -> response.sendRedirect("/");
//What i am trying to do...Need your help here
            return (request, response, authentication) -> {
                if(request.getSession().getAttribute("programs").equals("Certificate-program")){
                    response.sendRedirect("company");
                }else {
                    response.sendRedirect("/");
                }
            };
        }

        public AuthenticationFailureHandler loginFailureHandler() {
            return (request, response, exception) -> {
                request.getSession().setAttribute("flash", new FlashMessage("Incorrect username and/or password. Please try again.", FlashMessage.Status.FAILURE));
                response.sendRedirect("/login");
            };
        }

最佳答案

通过 Spring security 的表单登录,对安全资源的请求将被存储,并且当登录完成时,原始请求将被恢复并处理。在我看来,使用自定义 AuthenticationSuccessHandler 的方法是成功身份验证后重定向的好方法。

但是,您忘记了一件小事。如果您查看默认用于表单登录的 SavedRequestAwareAuthenticationSuccessHandler 的源代码,您会注意到它从 RequestCache 中删除了已保存的请求,您应该这样做相同或保存的请求继续存在于用户 session 中。

关于java - 在 Spring 中使用 AuthenticationSuccessHandler 重定向登录页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41911076/

相关文章:

java - 本程序无法显示网页:

java - WebSocket 握手期间出错(意外响应代码 : 400)

在循环中执行插入时出现 javax.persistence.TransactionRequiredException

java - Spring Boot 应用程序 Heroku PostgreSQL 错误 : GenerationTarget encountered exception accepting command : Error executing DDL . .. 通过 JDBC 语句

Java:如何使用JavaParser获取Java类的标识符数量

java - 我在 Spring Boot 版本 2.2.0 的 Spring Batch 中遇到错误

java - Spring JdbcTemplate - 如何将查询限制为 SELECT(s)?

java - 将流分配给变量 : Okay or Not?

java - BindingResult 和 bean 名称 'clsData' 的普通目标对象都不能作为请求属性

迭代器停止后,Java 不会更改接口(interface)上的值