我正在尝试将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();
}
答案 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"> </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);
}
}