成功登录后,下载文件而不是重定向到默认URL

时间:2019-02-16 11:14:28

标签: spring-boot spring-security

我正在尝试将Spring Security与数据库一起使用,并在遵循示例之后,我能够登录(称为onAuthenticationSuccess),但是我没有被重定向到默认页面,而是得到了一个空文件下载。 我期望将我重定向到默认页面defaultSuccessUrl("/", true)

@GetMapping(path = "/")
public String displayInitialPage(Model model) {
    return "index";
}

安全配置类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private WebApplicationContext applicationContext;

@Autowired
private UserService userDetailsService;

@Autowired
private DataSource dataSource;

@Autowired
private AuthenticationSuccessHandlerImpl successHandler;

@PostConstruct
public void completeSetup() {
    userDetailsService = applicationContext.getBean(UserService.class);
}

@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(encoder()).and()
            .authenticationProvider(authenticationProvider()).jdbcAuthentication().dataSource(dataSource);
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/register", "/style", "/script");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated().antMatchers("/login").permitAll().and().formLogin()
            .loginPage("/login").defaultSuccessUrl("/", true).permitAll().successHandler(successHandler).and().csrf().disable();
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}

@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder(11);
}

/**
 * Enables activation of automatic resolving of spring-data specific expressions annotated on classes
 * @return SecurityEvaluationContextExtension
 */
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
    return new SecurityEvaluationContextExtension();
}

2 个答案:

答案 0 :(得分:1)

这意味着浏览器无法识别响应,并假设它是文件(不得已)

您有这个控制器:

@GetMapping(path = "/")
public String displayInitialPage(Model model) {
    return "index";
}

因此,Spring将采用值"index"并尝试将其映射到某些内容。 这里的幕后发生了很多魔术。

假设您使用的是Spring Boot,并且有一个gradle构建,依赖项:

    compile group: "org.springframework.security", name: "spring-security-core", version: "$springSecurityVersion"
    compile group: "org.springframework.security", name: "spring-security-web", version: "$springSecurityVersion"
    compile group: "org.springframework.boot", name: "spring-boot-starter-web", version: "$springBootVersion"
    compile group: "org.springframework.boot", name: "spring-boot-starter-security", version: "$springBootVersion"
    compile group: "org.springframework.boot", name: "spring-boot-starter-thymeleaf", version: "$springBootVersion"
    compile group: "org.thymeleaf.extras", name: "thymeleaf-extras-springsecurity5", version: "$thymeleafExtrasSpringSecurityVersion"

注意最后两行。这些使 thymeleaf 成为模板引擎。 Spring将在目录中查找

./src/main/resources/templates

对于名为index.html的文件

该文件如下所示:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <title>Spring Security - Simple Flow for Spring Boot Authentication</title>
    <meta charset="utf-8" />
</head>
<body>
<div style="float: right" th:fragment="logout" sec:authorize="isAuthenticated()">
    <div style="float:left">
        <span style="font-weight:bold">User: </span><span sec:authentication="name"></span>
    </div>
    <div style="float:none">&nbsp;</div>
    <div style="float:right">
        <form action="#" th:action="@{/local/logout}" method="post">
            <input type="submit" value="Local Logout" />
        </form>
    </div>
</div>
<h1>Success</h1>
</body>
</html>

在Spring Web MVC中,有一个名为

的bean。
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/templates/");
        viewResolver.setSuffix(".html");
        ....
        return viewResolver;
    }

Spring Boot具有一个称为自动配置的组件。因此,它将查找存在的库并相应地配置解析器。 有用于旧版应用程序的JSP解析器,当您想将JSON,XML或其他格式发送回时,可以使用Content Mapping解析器,而我更喜欢的thymeleaf,则用于发送回HTML内容。

在任何给定时间,您都可以配置多个解析器。

我的社区存储库中有许多示例可供使用。

https://github.com/fhanik/spring-security-community/tree/master/samples

答案 1 :(得分:0)

我如下更改了安全配置类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserService userDetailsService;

@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/register", "/style", "/script");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated().antMatchers("/login").permitAll().and().formLogin()
            .loginPage("/login").defaultSuccessUrl("/", true).permitAll();
}

@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder(11);
}
}