#java #spring-boot #spring-mvc #spring-security
#java #spring-boot #spring-mvc #spring-безопасность
Вопрос:
Я пытаюсь добавить пользовательскую страницу входа в Sprint Security, но в итоге получается ошибка 404 «Страница не найдена». Я уже внедрил механизм входа в систему, и он работает для формы входа в систему Spring Security по умолчанию. Теперь я понятия не имею, что делать, чтобы заставить пользовательскую страницу входа работать.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.krzychu</groupId>
<artifactId>hairdresser</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hairdresser</name>
<description>Haidresser CRUD</description>
<properties>
<java.version>12</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SecurityConfig.java
package com.krzychu.hairdresser.config;
import com.krzychu.hairdresser.services.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@EnableWebMvc
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
login.html
<html xmlns:th="https://www.thymeleaf.org">
<head th:include="layout :: head(title=~{::title},links=~{})">
<title>Please Login</title>
</head>
<body th:include="layout :: body" th:with="content=~{::content}">
<div th:fragment="content">
<form name="f" th:action="@{/login}" method="post">
<fieldset>
<legend>Please Login</legend>
<div th:if="${param.error}" class="alert alert-error">
Invalid username and password.
</div>
<div th:if="${param.logout}" class="alert alert-success">
You have been logged out.
</div>
<label for="username">Username</label>
<input type="text" id="username" name="username"/>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
<div class="form-actions">
<button type="submit" class="btn">Log in</button>
</div>
</fieldset>
</form>
</div>
</body>
</html>
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=${DB_URL}
spring.datasource.username=
spring.datasource.password=
spring.main.allow-bean-definition-overriding=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
Комментарии:
1. Можете ли вы поделиться всем своим классом конфигурации?
2. Конечно, только что отредактированный пост
Ответ №1:
Вы можете заменить EnableWebMvc на EnableWebSecurity следующим образом
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// ...
}
Редактировать
Добавьте контроллер для входа в систему следующим образом
@Controller
public class LoginController {
@GetMapping("/login")
public String index(HttpServletRequest request, Model model) {
// ...
return "login";
}
}
В этом примере предполагается login.html
, что в вашей templates
папке есть файл
Редактировать 2
Если это еще не сделано, вы должны добавить a ViewResolver
как a @Bean
в свой класс конфигурации
@Bean
public TemplateEngine templateEngine(ITemplateResolver templateResolver, SpringSecurityDialect sec) {
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
templateEngine.addDialect(sec);
return templateEngine;
}
Добавьте эту зависимость
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Комментарии:
1. Это не помогло.
2. Возможно, вам необходимо предоставить дополнительный контент. Поделитесь своим
LoginController
3. У меня нет LoginController. Я думал, что мне это не нужно, не так ли?
4. Именно поэтому была отображена страница входа по умолчанию. Конечно, для этого вам нужен контроллер
5. @dm_tr Ну, я уверен, но даже после добавления этой зависимости она все равно не работает
Ответ №2:
почему не дают возможности удалить теги, у которых есть th:include=»layout , просто чтобы проверить, что подключение элементов выполнено правильно, и отсутствует только определение макета??