Spring Boot 1.5.9.RELEASE Java 8 Maven 4.0.0
Verwenden Sie Spring Security, um die Anmeldeinformationen in der Datenbank zu überprüfen und zu authentifizieren. DB verwendet H2DB und ORM verwendet Doma.
Generieren Sie ein Projekt mit Spring Inirializr.
Da wir diesmal Doma für ORM verwenden, legen Sie die Annotationsverarbeitung fest.
Es werden nur diejenigen aufgelistet, die gegenüber der Standardeinstellung geändert wurden.
pom.xml(※Auszug)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</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>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seasar.doma.boot/doma-spring-boot-starter -->
<dependency>
<groupId>org.seasar.doma.boot</groupId>
<artifactId>doma-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
UserEntity.java
package com.example.springbootsecuritysample.entity;
import java.util.Collection;
import org.seasar.doma.Entity;
import org.seasar.doma.Id;
import org.seasar.doma.jdbc.entity.NamingType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import lombok.Getter;
import lombok.Setter;
/**
*Entität in der USER-Tabelle
* @author T.Harao
*
*/
@Entity(naming = NamingType.SNAKE_UPPER_CASE)
@Getter
@Setter
public class UserEntity implements UserDetails {
@Id
private String userId;
private String password;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getUsername() {
return userId;
}
/**
*Geben Sie das von UserDetailsService zu überprüfende Kennwort zurück
*Wenn Sie Lombok verwenden, wenn das Feld "Passwort" hat
*GetPassword mit @Getter()Wird nicht benötigt, da es generiert wird
*/
@Override
public String getPassword() {
return password;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
UserDao.java
package com.example.springbootsecuritysample.dao;
import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;
import com.example.springbootsecuritysample.entity.UserEntity;
/**
*DAO greift auf die USER-Tabelle zu
* @author T.Harao
*
*/
@Dao
@ConfigAutowireable
public interface UserDao {
@Select
public UserEntity selectByUserId(String userId);
}
AuthService.java
package com.example.springbootsecuritysample.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.example.springbootsecuritysample.dao.UserDao;
import com.example.springbootsecuritysample.entity.UserEntity;
/**
*Dienst, der die Authentifizierung übernimmt
* @author T.Harao
*
*/
@Service
public class AuthService implements UserDetailsService {
@Autowired
private UserDao dao;
/**
*Benutzer wird geladen
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(username == null || "".equals(username)) {
throw new UsernameNotFoundException("Benutzer-ID wurde nicht eingegeben");
}
UserEntity user = dao.selectByUserId(username);
if(user == null) {
throw new UsernameNotFoundException("Die Benutzer-ID ist ungültig.");
}
return user;
}
}
IndexForm.java
package com.example.springbootsecuritysample.form;
import org.hibernate.validator.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
/**
*Von IndexController verwendetes Formular
* @author T.Harao
*
*/
@Getter
@Setter
public class IndexForm {
@NotEmpty
private String userId;
@NotEmpty
private String password;
}
IndexController.java
package com.example.springbootsecuritysample.controller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.example.springbootsecuritysample.form.IndexForm;
/**
*Einloggen
* @author T.Harao
*
*/
@Controller
@RequestMapping({"/", "/index"})
public class IndexController {
@ModelAttribute
public IndexForm initForm(){
return new IndexForm();
}
/**
*Erstanzeige
* @param mv
* @return
*/
@RequestMapping(value = {"/", "/index"}, method = RequestMethod.GET)
public ModelAndView index(ModelAndView mv) {
mv.setViewName("index/index");
return mv;
}
/**
*Zum Zeitpunkt des Authentifizierungsfehlers
* @param mv
* @return
*/
@RequestMapping(value = {"/", "/index"}, method = RequestMethod.POST)
public ModelAndView login(@ModelAttribute @Validated IndexForm form, BindingResult result, ModelAndView mv) {
if(!result.hasErrors()) {
mv.addObject("errorMessage", "Falsche Anmeldeinformationen");
}
mv.setViewName("index/index");
return mv;
}
}
MenuController.java
package com.example.springbootsecuritysample.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
*Speisekarte
* @author T.Harao
*
*/
@Controller
@RequestMapping("/menu")
public class MenuController {
/**
*Erstanzeige
* @param mv
* @return
*/
@RequestMapping(value = {"/", "/index"}, method = RequestMethod.GET)
public ModelAndView index(ModelAndView mv) {
mv.setViewName("menu/index");
return mv;
}
}
FailureHandler.java
package com.example.springbootsecuritysample.config.handler;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
/**
*Handler, wenn die Authentifizierung fehlschlägt
* @author T.Harao
*
*/
@Component
public class FailureHandler implements AuthenticationFailureHandler {
/**
*Wenn die Authentifizierung fehlschlägt
*/
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
//「/Weiterleiten
RequestDispatcher dispatch = request.getRequestDispatcher("/");
dispatch.forward(request, response);
}
}
SuccessHandler.java
package com.example.springbootsecuritysample.config.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
/**
*Handler bei erfolgreicher Authentifizierung
* @author T.Harao
*
*/
@Component
public class SuccessHandler implements AuthenticationSuccessHandler {
/**
*Wenn die Authentifizierung erfolgreich ist
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
//「/menu/Weiterleiten an
response.sendRedirect(request.getContextPath() + "/menu/");
}
}
SecurityConfig.java
package com.example.springbootsecuritysample.config;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import com.example.springbootsecuritysample.config.handler.FailureHandler;
import com.example.springbootsecuritysample.config.handler.SuccessHandler;
import com.example.springbootsecuritysample.service.AuthService;
/**
*Sicherheitseinstellungen
* @author T.Harao
*
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthService service;
@Autowired
private FailureHandler failureHandler;
@Autowired
private SuccessHandler successHandler;
/**
*Web-Sicherheitseinstellungen
*/
@Override
public void configure(WebSecurity web) throws Exception {
//Statische Ressourcen(images、css、javascript)Beim Zugriff auf die H2DB-Konsole werden die Sicherheitseinstellungen ignoriert
web.ignoring().antMatchers("/css/**", "/fonts/**", "/images/**", "/js/**", "/h2-console/**");
}
/**
*HttpSecurity-Einstellungen
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//Autorisierungseinstellungen
http.authorizeRequests()
//Legen Sie eine URL fest, auf die ohne Authentifizierung zugegriffen werden kann
.antMatchers("/", "/index/**").permitAll()
//Für die Authentifizierung sind andere als die oben genannten Einstellungen erforderlich
.anyRequest().authenticated();
//Login-Einstellungen
http.formLogin()
//Legen Sie den Pfad für die Authentifizierungsverarbeitung fest
.loginProcessingUrl("/index/login")
//Legen Sie den Anmeldeformularpfad fest
.loginPage("/")
.loginPage("/index/**")
//Stellen Sie die URL so ein, dass sie nach erfolgreicher Authentifizierung umgeleitet wird
.defaultSuccessUrl("/menu/")
//Legen Sie die URL fest, die weitergeleitet werden soll, wenn die Authentifizierung fehlschlägt
.failureForwardUrl("/")
//Legen Sie die URL fest, die bei erfolgreicher Authentifizierung weitergeleitet werden soll
//.successForwardUrl("/")
//Legen Sie die Handlerklasse fest, die aufgerufen werden soll, wenn die Authentifizierung erfolgreich ist
//.successHandler(successHandler)
//Legen Sie die URL fest, die umgeleitet werden soll, wenn die Authentifizierung fehlschlägt
//.failureUrl("/menu/")
//Legen Sie eine Handlerklasse fest, die aufgerufen werden soll, wenn die Authentifizierung fehlschlägt
//.failureHandler(failureHandler)
//Legen Sie den Namen des Benutzernamens und des Kennwortparameters fest
.usernameParameter("userId").passwordParameter("password");
}
/**
*Aufbau
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//Setzen Sie "NoOpPasswordEncoder", da das Passwort im Klartext in der Datenbank registriert ist.
auth.userDetailsService(service)
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
layout.html
<!DOCTYPE html>
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:th = "http://www.thymeleaf.org"
xmlns:layout = "http://www.ultraq.net.nz/thymeleaf/layout"
>
<head>
<meta charset="UTF-8" />
<title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Frühlingssicherheitstest</title>
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" media="all" />
<link rel="stylesheet" type="text/css" href="/css/bootstrap-theme.min.css" th:href="@{/css/bootstrap-theme.min.css}" media="all" />
<script type="text/javascript" src="/js/jquery-1.12.4.min.js" th:src="@{/js/jquery-1.12.4.min.js}"></script>
<script type="text/javascript" src="/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<div class="contents" layout:fragment="contents"></div>
</body>
</html>
index/index.html
<!DOCTYPE html>
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:th = "http://www.thymeleaf.org"
xmlns:layout = "http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout"
>
<head>
<title>Einloggen</title>
</head>
<body>
<div layout:fragment="contents">
<form class="form-horizontal" method="POST" action="/index/login/" th:action="@{/index/login}" th:object="${indexForm}">
<div th:text="${errorMessage}?: ''" class="col-sm-offset-2 text-danger"></div>
<div class="form-group">
<p th:if="${#fields.hasErrors('*{userId}')}" th:errors="*{userId}" class="col-sm-offset-2 text-danger"></p>
<label for="user-id" class="col-sm-2 control-label">Benutzeridentifikation</label>
<div class="col-sm-5">
<input type="text" class="form-control" id="user-id" th:field="*{userId}" placeholder="Benutzeridentifikation" />
</div>
</div>
<div class="form-group">
<p th:if="${#fields.hasErrors('*{password}')}" th:errors="*{password}" class="col-sm-offset-2 text-danger"></p>
<label for="password" class="col-sm-2 control-label">Passwort</label>
<div class="col-sm-5">
<input type="password" class="form-control" id="password" th:field="*{password}" placeholder="Passwort" />
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary col-sm-2 col-sm-offset-2" name="login" value="Einloggen" />
<input type="reset" class="btn btn-default col-sm-2 col-sm-offset-1" name="clear" value="klar" />
</div>
</form>
</div>
</body>
</html>
menu/index.html
<!DOCTYPE html>
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:th = "http://www.thymeleaf.org"
xmlns:layout = "http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout"
>
<head>
<title>Speisekarte</title>
</head>
<body>
<div layout:fragment="contents">
<h2>Speisekarte</h2>
</div>
</body>
</html>
application.yaml
#spring
spring:
profiles:
active: dev
datasource:
url: jdbc:h2:./db
#server
server:
contextPath: /security-sample
#doma
doma:
dialect: h2
application-dev.yaml
#spring
spring:
h2:
console:
enabled: true
thymeleaf:
cache: false
application-production.yaml
#spring
spring:
h2:
console:
enabled: false
thymeleaf:
cache: true
selectByUserId.sql
select
user_id
,password
from
user
where
user_id = /*userId*/''
schema.sql
--drop table if exists user;
create table if not exists user (
user_id varchar(30) not null primary key
,password varchar(30) not null
);
data.sql
insert into user (user_id,password) values ('test','pass');
Die Ordnerstruktur ist wie folgt.
Greifen Sie auf [http: // localhost: 8080 / security-sample /](http: // localhost: 8080 / security-sample /) zu und gehen Sie zu Geben Sie "test" als Benutzer-ID und "pass" als Passwort ein, um zum Menübildschirm zu gelangen. Anmeldebildschirm Menübildschirm
Die Verarbeitung, wenn die Authentifizierung erfolgreich ist oder fehlschlägt, wird im folgenden Teil von "SecurityConfig.java" beschrieben.
SecurityConfig.java
/**
*HttpSecurity-Einstellungen
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//Autorisierungseinstellungen
http.authorizeRequests()
//Legen Sie eine URL fest, auf die ohne Authentifizierung zugegriffen werden kann
.antMatchers("/", "/index/**").permitAll()
//Für die Authentifizierung sind andere als die oben genannten Einstellungen erforderlich
.anyRequest().authenticated();
//Login-Einstellungen
http.formLogin()
//Legen Sie den Pfad für die Authentifizierungsverarbeitung fest
.loginProcessingUrl("/index/login")
//Legen Sie den Anmeldeformularpfad fest
.loginPage("/")
.loginPage("/index/**")
//Stellen Sie die URL so ein, dass sie nach erfolgreicher Authentifizierung umgeleitet wird
.defaultSuccessUrl("/menu/")
//Legen Sie die URL fest, die weitergeleitet werden soll, wenn die Authentifizierung fehlschlägt
.failureForwardUrl("/")
//Legen Sie die URL fest, die bei erfolgreicher Authentifizierung weitergeleitet werden soll
//.successForwardUrl("/")
//Legen Sie die Handlerklasse fest, die aufgerufen werden soll, wenn die Authentifizierung erfolgreich ist
//.successHandler(successHandler)
//Legen Sie die URL fest, die umgeleitet werden soll, wenn die Authentifizierung fehlschlägt
//.failureUrl("/menu/")
//Legen Sie eine Handlerklasse fest, die aufgerufen werden soll, wenn die Authentifizierung fehlschlägt
//.failureHandler(failureHandler)
//Legen Sie den Namen des Benutzernamens und des Kennwortparameters fest
.usernameParameter("userId").passwordParameter("password");
}
Ich habe auskommentiert, aber wenn die Authentifizierung erfolgreich ist und fehlschlägt Sie können die Verarbeitung umleiten, weiterleiten und an die Handlerklasse delegieren.
Das diesmal erstellte Projekt befindet sich in hier
Recommended Posts