我已經開發出一種應用(SpringBootWebSecurity
)與ThymeLeaf
和Gradle
。用戶可以使用thymeleaf
表單登錄。爲什麼用戶無法在春季啓動應用程序登錄?
然後,我開發了另一種新的應用程序(SpringBootJSP
)維持先前的結構(SpringBootWebSecurity
),但這個時候,我只是改變了構建工具(maven
)和視圖(jsp
)以適當的依賴關係。兩個應用程序的數據庫和其他憑證保持不變。 (多個)用戶是/是無法與jsp
應用登錄。
結構
![application structures][1]
LoginCtroller.java
package com.maxpro.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
private final String BASE_PATH = "/login";
private final String LOGIN_PAGE = BASE_PATH + "/login";
@RequestMapping("/login")
public String login() {
return LOGIN_PAGE;
}
}
視圖
login.html
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link th:href="@{/css/admin/admin.css}" rel="stylesheet"/>
</head>
<body>
<div class="container">
<div class="alert alert-danger" th:if="${param.error}">
<strong>Invalid username or password or both.</strong>
</div>
<form class="form-signin" th:action="@{/login}" method="post">
<h2 class="form-signin-heading text-center">sign in</h2>
<input type="text" id="inputName" name="username" class="form-control" placeholder="Username"
required="required" autofocus="autofocus"/>
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password"
required="required"/>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
login.jsp
<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- home.css -->
<link rel="stylesheet" href="<c:url value = "/css/admin/admin.css"/>"/>
<!-- /home.css -->
</head>
<body>
<div class="container">
<c:if test="${param.error}">
<div class="alert alert-danger">
<strong>Invalid username or password or both.</strong>
</div>
</c:if>
<form class="form-signin" action="<c:url value="/login"/>" method="post">
<h2 class="form-signin-heading text-center">sign in</h2>
<input type="text" id="inputName" name="username" class="form-control" placeholder="Username"
required="required" autofocus="autofocus"/>
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password"
required="required"/>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
WebSecurityConfigurer.java & WebUserDetailsService.java(這些類用於propcess用戶登錄)
WebSecurityConfigurer.java
package com.maxpro.configuration.security;
import com.maxpro.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceBean()).passwordEncoder(passwordEncoder());
}
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new WebUserDetailsService(userRepository);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/img/**", "/js/**").permitAll()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
.antMatchers("/user/**").hasAuthority("ROLE_USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username").passwordParameter("password").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedPage("/access-denied")
.and()
.sessionManagement()
// .and()
// .csrf();
;
}
}
WebUserDetailsService.java
package com.maxpro.configuration.security;
import com.maxpro.entity.Role;
import com.maxpro.entity.User;
import com.maxpro.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import javax.transaction.Transactional;
import java.util.HashSet;
import java.util.Set;
@Transactional
public class WebUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
public WebUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userRepository.findByUserName(username);
if (user == null) {
return null;
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), getAuthorities(user));
} catch (Exception e) {
throw new UsernameNotFoundException("User not found");
}
}
private Set<GrantedAuthority> getAuthorities(User user) {
Set<GrantedAuthority> authorities = new HashSet<>();
for (Role role : user.getRoles()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
authorities.add(grantedAuthority);
}
return authorities;
}
}
application.properties
在SpringBootWebSecurity
應用:
#configurations
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
#initializations
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
#credentials
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot_security
spring.datasource.username=root
spring.datasource.password=ENC(fwPDBYsbkbHVwxDGEsutsQ==)
spring.datasource.schema=classpath:/data/schema.sql
在SpringBootJSP
應用下面的行的情況下加入:
spring.mvc.view.prefix: /WEB-INF/jsp
spring.mvc.view.suffix: .jsp
application.message: Hello World!!
.
.
.
## following line commented
#spring.datasource.schema=classpath:/data/schema.sql
觀測
在上WebUserDetailsService.java
類SpringBootWebSecurity
命中登錄表單的情況下。在另一方面,SpringBootJSP
不能這樣做。
問題
這究竟是爲什麼在SpringBootJSP
情況?
項目位置