基本完成登录系统的建设

This commit is contained in:
Saturneric 2020-02-14 15:59:40 +08:00
parent 8b04a9c422
commit 1180533832
20 changed files with 294 additions and 34 deletions

View File

@ -2,6 +2,7 @@ package com.codesdream.ase;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication @SpringBootApplication
public class AseApplication { public class AseApplication {

View File

@ -13,6 +13,6 @@ public class ASEPasswordEncoder implements PasswordEncoder {
@Override @Override
public boolean matches(CharSequence charSequence, String s) { public boolean matches(CharSequence charSequence, String s) {
return s.equals(charSequence.toString()); return s.equals(DigestUtils.sha256Hex(charSequence.toString()));
} }
} }

View File

@ -12,8 +12,13 @@ import java.util.Collection;
*/ */
@Component @Component
public class UserFunctionalPermissionContainersListGenerator { public class UserFunctionalPermissionContainersListGenerator {
@Resource
UserFunctionalScopeRelationsListGenerator functionalScopeRelationsListGenerator; private UserFunctionalScopeRelationsListGenerator functionalScopeRelationsListGenerator;
public UserFunctionalPermissionContainersListGenerator(){
this.functionalScopeRelationsListGenerator =
new UserFunctionalScopeRelationsListGenerator();
}
public Collection<FunctionalPermissionContainer> generateFunctionalContainers( public Collection<FunctionalPermissionContainer> generateFunctionalContainers(
Collection<FunctionalScopeRelation> functionalScopeRelations){ Collection<FunctionalScopeRelation> functionalScopeRelations){

View File

@ -14,8 +14,13 @@ import java.util.Collection;
*/ */
@Component @Component
public class UserFunctionalScopeRelationsListGenerator { public class UserFunctionalScopeRelationsListGenerator {
@Resource
UserPermissionContainersCollectionsListGenerator userPermissionContainersCollectionsListGenerator; private UserPermissionContainersCollectionsListGenerator userPermissionContainersCollectionsListGenerator;
public UserFunctionalScopeRelationsListGenerator(){
this.userPermissionContainersCollectionsListGenerator =
new UserPermissionContainersCollectionsListGenerator();
}
public Collection<FunctionalScopeRelation> generateFunctionalScopeRelations( public Collection<FunctionalScopeRelation> generateFunctionalScopeRelations(
Collection<PermissionContainersCollection> permissionContainersCollections){ Collection<PermissionContainersCollection> permissionContainersCollections){

View File

@ -16,8 +16,13 @@ import java.util.Optional;
*/ */
@Component @Component
public class UserPermissionContainersCollectionsListGenerator { public class UserPermissionContainersCollectionsListGenerator {
@Resource
UserTagsListGenerator userTagsListGenerator; private UserTagsListGenerator userTagsListGenerator;
public UserPermissionContainersCollectionsListGenerator(){
this.userTagsListGenerator =
new UserTagsListGenerator();
}
public Collection<PermissionContainersCollection> generatePermissionContainerCollections( public Collection<PermissionContainersCollection> generatePermissionContainerCollections(
Collection<Tag> tags){ Collection<Tag> tags){

View File

@ -2,6 +2,7 @@ package com.codesdream.ase.component;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer; import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import com.codesdream.ase.model.permission.User; import com.codesdream.ase.model.permission.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -16,8 +17,13 @@ import java.util.Optional;
*/ */
@Component @Component
public class UserRolesListGenerator { public class UserRolesListGenerator {
@Resource
UserFunctionalPermissionContainersListGenerator functionalPermissionContainersListGenerator; private UserFunctionalPermissionContainersListGenerator functionalPermissionContainersListGenerator;
public UserRolesListGenerator(){
this.functionalPermissionContainersListGenerator =
new UserFunctionalPermissionContainersListGenerator();
}
public Collection<GrantedAuthority> generateRoles( public Collection<GrantedAuthority> generateRoles(
Collection<FunctionalPermissionContainer> functionalPermissionContainers){ Collection<FunctionalPermissionContainer> functionalPermissionContainers){
@ -37,6 +43,7 @@ public class UserRolesListGenerator {
} }
public Collection<GrantedAuthority> generateRoles(User user){ public Collection<GrantedAuthority> generateRoles(User user){
return generateRoles( return generateRoles(
functionalPermissionContainersListGenerator.generateFunctionalPermissionContainers(user) functionalPermissionContainersListGenerator.generateFunctionalPermissionContainers(user)
); );

View File

@ -20,10 +20,10 @@ import javax.annotation.Resource;
@EnableWebSecurity @EnableWebSecurity
public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter { public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Resource
ASEUserDetailsService aseUserDetailService; ASEUserDetailsService aseUserDetailService;
@Autowired @Resource
ASEPasswordEncoder asePasswordEncoder; ASEPasswordEncoder asePasswordEncoder;
@Override @Override
@ -33,9 +33,8 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
.and() .and()
.csrf().disable().formLogin() .csrf().disable().formLogin()
.and() .and()
.formLogin().loginPage("/login").permitAll().defaultSuccessUrl("/").permitAll() .formLogin().loginPage("/login")
.usernameParameter("username") .permitAll().defaultSuccessUrl("/").permitAll()
.passwordParameter("password")
.and() .and()
.logout().permitAll(); .logout().permitAll();
@ -43,13 +42,14 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("普通用户"); auth.userDetailsService(aseUserDetailService)
.passwordEncoder(asePasswordEncoder);
} }
@Override @Override
public void configure(WebSecurity web) throws Exception { public void configure(WebSecurity web) throws Exception {
web web
.ignoring() .ignoring()
.antMatchers("/assets/**"); .antMatchers("/assets/**", "/register/**", "/forget/**", "/not_found/**");
} }
} }

View File

@ -1,4 +1,61 @@
package com.codesdream.ase.controller; package com.codesdream.ase.controller;
import com.codesdream.ase.component.ASEPasswordEncoder;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.UserRepository;
import com.codesdream.ase.service.UserService;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
@Controller
public class RegisterController { public class RegisterController {
@Resource
UserService userService;
@RequestMapping(value = "/register")
String registerView(Model model){
return "register";
}
// 处理注册表单
@PostMapping(value = "/register")
String doRegister(Model model, HttpServletRequest request){
Map<String, String[]> parameterMap= request.getParameterMap();
// 进行处理前的检查
if(parameterMap.containsKey("username")
&& parameterMap.containsKey("password")
&& parameterMap.containsKey("retry-password")
&& parameterMap.containsKey("user-question")
&& parameterMap.containsKey("user-answer")
) {
User user = userService.getDefaultUser();
user.setUsername(parameterMap.get("username")[0].toString());
String password = parameterMap.get("password")[0].toString();
String retry_password = parameterMap.get("retry-password")[0].toString();
if (password.equals(retry_password)) {
user.setPassword(password);
userService.save(user);
return "index";
}
}
return "register";
}
} }

View File

@ -25,10 +25,6 @@ public class User implements UserDetails {
@Column(nullable = false) @Column(nullable = false)
private String password; private String password;
// 手机号
@Column(nullable = true)
private String phone_number;
// 账号是否过期 // 账号是否过期
private boolean accountNonExpired; private boolean accountNonExpired;
@ -57,7 +53,7 @@ public class User implements UserDetails {
this.username = username; this.username = username;
this.password = password; this.password = password;
initUserDefault(); initDefault();
} }
public User() { public User() {
@ -65,16 +61,18 @@ public class User implements UserDetails {
this.password = null; this.password = null;
this.deleted = false; this.deleted = false;
initUserDefault(); initDefault();
} }
// 用默认的方式初始化User对象的值 // 用默认的方式初始化User对象的值
private void initUserDefault(){ private void initDefault(){
this.accountNonExpired = true; this.accountNonExpired = true;
this.accountNonLocked = true; this.accountNonLocked = true;
this.credentialsNonExpired = true; this.credentialsNonExpired = true;
this.deleted = false; this.deleted = false;
this.enabled = true;
this.tags = new HashSet<>(); this.tags = new HashSet<>();
this.userDetail = new UserDetail();
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.codesdream.ase.service; package com.codesdream.ase.service;
import com.codesdream.ase.model.permission.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
@ -7,6 +8,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import java.util.Optional;
@Service @Service
public class ASEUserDetailsService implements UserDetailsService { public class ASEUserDetailsService implements UserDetailsService {
@ -17,11 +19,15 @@ public class ASEUserDetailsService implements UserDetailsService {
@Override @Override
@Transactional @Transactional
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
if(!userService.findUserByUsername(s).isPresent()){ System.out.println("User: " + s);
throw new UsernameNotFoundException("用户不存在"); Optional<User> user = userService.findUserByUsername(s);
if(!user.isPresent()){
throw new UsernameNotFoundException("User Not Found");
} }
else { else {
return userService.findUserByUsername(s).get(); System.out.println("Returning user information");
System.out.println("User Password: "+user.get().getPassword());
return user.get();
} }
} }
} }

View File

@ -0,0 +1,4 @@
package com.codesdream.ase.service;
public interface IPermissionService {
}

View File

@ -12,4 +12,7 @@ public interface IUserService {
Optional<User> findUserById(int id); Optional<User> findUserById(int id);
Optional<User> findUserByUsername(String username); Optional<User> findUserByUsername(String username);
User save(User user); User save(User user);
// 获得默认用户
User getDefaultUser();
} }

View File

@ -0,0 +1,8 @@
package com.codesdream.ase.service;
import org.springframework.stereotype.Service;
@Service
public class PermissionService implements IPermissionService {
}

View File

@ -34,11 +34,18 @@ public class UserService implements IUserService {
@Override @Override
public User save(User user) { public User save(User user) {
if(userRepository.findByUsername(user.getUsername()).isPresent())
throw new RuntimeException("Username Already Exists");
user.setPassword(asePasswordEncoder.encode(user.getPassword())); user.setPassword(asePasswordEncoder.encode(user.getPassword()));
user.setEnabled(true); user.setEnabled(true);
user.setDeleted(false); user.setDeleted(false);
return userRepository.save(user); return userRepository.save(user);
} }
@Override
public User getDefaultUser() {
return new User();
}
} }

View File

@ -9,6 +9,8 @@ spring.jpa.generate-ddl=false
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=update
spring.jooq.sql-dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jooq.sql-dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.open-in-view=true
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:119.23.9.34}:3306/ase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.url=jdbc:mysql://${MYSQL_HOST:119.23.9.34}:3306/ase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=codedream spring.datasource.username=codedream

View File

@ -0,0 +1,23 @@
<!doctype html>
<html>
<head>
<link href="../static/assets/css/atlantis.css" rel="stylesheet" type="text/css" media="screen">
<link href="../static/assets/css/atlantis.css.map.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/atlantis.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/demo.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/fonts.css" rel="stylesheet" type="text/css"><link href="../static/assets/css/fonts.min.css" rel="stylesheet" type="text/css">
<div th:include="layout::head"></div>
<meta charset="utf-8">
<title>error</title>
</head>
<body>
<div class="logo-header" data-background-color="blue" style="width:100%">
<h1><font color="#FFFFFF">Error</font></h1>
</div>
</body>
</html>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<link href="../static/assets/css/atlantis.css" rel="stylesheet" type="text/css" media="screen">
<link href="../static/assets/css/atlantis.css.map.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/atlantis.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/demo.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/fonts.css" rel="stylesheet" type="text/css"><link href="../static/assets/css/fonts.min.css" rel="stylesheet" type="text/css">
<div th:include="layout::head"></div>
</head>
<body>
<div th:fragment="content">
<div class="wrapper">
<div class="row" style="height: 15%"></div>
<div class="row" style="height: 70%">
<div class="col-md-3 ml-auto mr-auto">
<div class="card">
<div class="card-header">
<h4 class="card-title">重置密码</h4>
</div>
<form action="/login" method="post">
<div class="card-body">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名" style="width:70%,display:inline,float:left" >
<buttontype="submit" class="btn btn-primary btn-block"><b>获取密保问题</b></button>
</div>
<div class="form-group">
<label for="userquestion">(密保问题)</label>
<input type="text" class="form-control" id="answer" name="answer" placeholder="这里输入答案">
</div>
<div class="form-group">
<label for="password">新密码</label>
<input type="password" class="form-control" id="password" name="password" placeholder="这里输入新密码">
</div>
</div>
<div class="card-action">
<button type="submit" class="btn btn-primary btn-block"><b>提交</b></button>
</div>
</form>
</div>
</div>
</div>
<div th:include="layout::custom-template"></div>
</div>
</div>
<div th:include="layout::js"></div>
</body>
</html>

View File

@ -2,14 +2,13 @@
<html lang="en" <html lang="en"
xmlns:th="http://www.thymeleaf.org"> xmlns:th="http://www.thymeleaf.org">
<head> <head>
<div th:include="layout::head"></div> <div th:include="layout::head"></div>
</head> </head>
<body> <body>
<div th:fragment="content"> <div th:fragment="content">
<div class="wrapper"> <div class="wrapper">
<div class="row" style="height: 15%"></div> <div class="row" style="height: 15%"></div>
<div class="row" style="height: 70%; color: #9A9A9A;"> <div class="row" style="height: 70%">
<div class="col-md-3 ml-auto mr-auto"> <div class="col-md-3 ml-auto mr-auto">
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
@ -19,20 +18,20 @@
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="form-group">
<label for="username">用户名</label> <label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名"> <input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">密码</label> <label for="password">密码</label>
<span style="color: #F89798"></span> <input type="password" class="form-control" id="password" name="password" placeholder="这里输入密码" required>
<input type="password" class="form-control" id="password" name="password" placeholder="这里输入密码">
</div> </div>
</div> </div>
<div class="card-action"> <div class="card-action">
<button type="submit" class="btn btn-primary btn-block"><b>登录</b></button> <button type="submit" class="btn btn-primary btn-block"><b>登录</b></button>
</div> </div>
<button type="submit" class="btn-link"><b>忘记密码</b></button>
<button type="submit" class="btn-link"><b>注册账号</b></button>
</form> </form>
<a class="btn-link" th:href="@{/forget}"><b>忘记密码</b></a>
<a class="btn-link" th:href="@{/register}"><b>注册账号</b></a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,23 @@
<!doctype html>
<html>
<head>
<link href="../static/assets/css/atlantis.css" rel="stylesheet" type="text/css" media="screen">
<link href="../static/assets/css/atlantis.css.map.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/atlantis.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/demo.css" rel="stylesheet" type="text/css">
<link href="../static/assets/css/fonts.css" rel="stylesheet" type="text/css"><link href="../static/assets/css/fonts.min.css" rel="stylesheet" type="text/css">
<div th:include="layout::head"></div>
<meta charset="utf-8">
<title>notfound</title>
</head>
<body>
<div class="logo-header" data-background-color="blue" style="width:100%">
<h1><font color="#FFFFFF">404 Not Found</font></h1>
</div>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<div th:include="layout::head"></div>
</head>
<body>
<div th:fragment="content">
<div class="wrapper">
<div class="row" style="height: 5%"></div>
<div class="row" style="height: 70%">
<div class="col-md-3 ml-auto mr-auto">
<div class="card">
<div class="card-header">
<h4 class="card-title">注册</h4>
</div>
<form action="/register" method="post">
<div class="card-body">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="这里输入用户名">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" id="password" name="password" placeholder="这里输入密码">
</div>
<div class="form-group">
<label for="retry-password">确认密码</label>
<input type="password" class="form-control" id="retry-password" name="retry-password" placeholder="这里输入密码">
</div>
<div class="form-group">
<label for="user-question">密保问题</label>
<input type="text" class="form-control" id="user-question" name="user-question" placeholder="不可修改,请谨慎填写">
</div><div class="form-group">
<label for="user-answer">答案</label>
<input type="text" class="form-control" id="user-answer" name="user-answer" placeholder="不可修改,请谨慎填写">
</div>
</div>
<div class="card-action">
<button type="submit" class="btn btn-primary btn-block"><b>注册</b></button>
</div>
</form>
</div>
</div>
</div>
<div th:include="layout::custom-template"></div>
</div>
</div>
<div th:include="layout::js"></div>
</body>
</html>