From 7226c3c291ebe31c58f62f12780e9f709df8a20c Mon Sep 17 00:00:00 2001 From: mrbird <852252810@qq.com> Date: Fri, 14 Sep 2018 09:02:17 +0800 Subject: [PATCH] =?UTF-8?q?Spring=20Security=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 35.Spring-Security-Authentication/pom.xml | 58 +++++++++++ .../java/cc/mrbird/SecurityApplication.java | 12 +++ .../main/java/cc/mrbird/domain/MyUser.java | 67 +++++++++++++ .../MyAuthenticationFailureHandler.java | 29 ++++++ .../MyAuthenticationSucessHandler.java | 40 ++++++++ .../browser/BrowserSecurityConfig.java | 43 ++++++++ .../security/browser/UserDetailService.java | 32 ++++++ .../controller/BrowserSecurityController.java | 39 ++++++++ .../mrbird/web/controller/TestController.java | 20 ++++ .../src/main/resources/application.yml | 3 + .../main/resources/resources/css/login.css | 97 +++++++++++++++++++ .../src/main/resources/resources/login.html | 18 ++++ 12 files changed, 458 insertions(+) create mode 100644 35.Spring-Security-Authentication/pom.xml create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/SecurityApplication.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/domain/MyUser.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationFailureHandler.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationSucessHandler.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/BrowserSecurityConfig.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/UserDetailService.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/BrowserSecurityController.java create mode 100644 35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/TestController.java create mode 100644 35.Spring-Security-Authentication/src/main/resources/application.yml create mode 100644 35.Spring-Security-Authentication/src/main/resources/resources/css/login.css create mode 100644 35.Spring-Security-Authentication/src/main/resources/resources/login.html diff --git a/35.Spring-Security-Authentication/pom.xml b/35.Spring-Security-Authentication/pom.xml new file mode 100644 index 0000000..bfee0e1 --- /dev/null +++ b/35.Spring-Security-Authentication/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + cc.mrbird + Security + 1.0-SNAPSHOT + jar + + Security + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.5.14.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.apache.commons + commons-lang3 + 3.7 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/SecurityApplication.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/SecurityApplication.java new file mode 100644 index 0000000..4740934 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/SecurityApplication.java @@ -0,0 +1,12 @@ +package cc.mrbird; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SecurityApplication { + + public static void main(String[] args) { + SpringApplication.run(SecurityApplication.class, args); + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/domain/MyUser.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/domain/MyUser.java new file mode 100644 index 0000000..dee4f7f --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/domain/MyUser.java @@ -0,0 +1,67 @@ +package cc.mrbird.domain; + +import java.io.Serializable; + +public class MyUser implements Serializable { + private static final long serialVersionUID = 3497935890426858541L; + + private String userName; + + private String password; + + private boolean accountNonExpired = true; + + private boolean accountNonLocked= true; + + private boolean credentialsNonExpired= true; + + private boolean enabled= true; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isAccountNonExpired() { + return accountNonExpired; + } + + public void setAccountNonExpired(boolean accountNonExpired) { + this.accountNonExpired = accountNonExpired; + } + + public boolean isAccountNonLocked() { + return accountNonLocked; + } + + public void setAccountNonLocked(boolean accountNonLocked) { + this.accountNonLocked = accountNonLocked; + } + + public boolean isCredentialsNonExpired() { + return credentialsNonExpired; + } + + public void setCredentialsNonExpired(boolean credentialsNonExpired) { + this.credentialsNonExpired = credentialsNonExpired; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationFailureHandler.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationFailureHandler.java new file mode 100644 index 0000000..22127b4 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationFailureHandler.java @@ -0,0 +1,29 @@ +package cc.mrbird.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { + + @Autowired + private ObjectMapper mapper; + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().write(mapper.writeValueAsString(exception.getMessage())); + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationSucessHandler.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationSucessHandler.java new file mode 100644 index 0000000..8dc29d3 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/handler/MyAuthenticationSucessHandler.java @@ -0,0 +1,40 @@ +package cc.mrbird.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class MyAuthenticationSucessHandler implements AuthenticationSuccessHandler { + + // private RequestCache requestCache = new HttpSessionRequestCache(); + + private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); + // + // @Autowired + // private ObjectMapper mapper; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException { + // response.setContentType("application/json;charset=utf-8"); + // response.getWriter().write(mapper.writeValueAsString(authentication)); + // SavedRequest savedRequest = requestCache.getRequest(request, response); + // System.out.println(savedRequest.getRedirectUrl()); + // redirectStrategy.sendRedirect(request, response, savedRequest.getRedirectUrl()); + redirectStrategy.sendRedirect(request, response, "/index"); + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/BrowserSecurityConfig.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/BrowserSecurityConfig.java new file mode 100644 index 0000000..92a0ea4 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/BrowserSecurityConfig.java @@ -0,0 +1,43 @@ +package cc.mrbird.security.browser; + +import cc.mrbird.handler.MyAuthenticationFailureHandler; +import cc.mrbird.handler.MyAuthenticationSucessHandler; +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.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private MyAuthenticationSucessHandler authenticationSucessHandler; + + @Autowired + private MyAuthenticationFailureHandler authenticationFailureHandler; + + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.formLogin() // 表单登录 + // http.httpBasic() // HTTP Basic + .loginPage("/authentication/require") // 登录跳转 URL + .loginProcessingUrl("/login") // 处理表单登录 URL + .successHandler(authenticationSucessHandler) // 处理登录成功 + .failureHandler(authenticationFailureHandler) // 处理登录失败 + .and() + .authorizeRequests() // 授权配置 + .antMatchers("/authentication/require", "/login.html").permitAll() // 登录跳转 URL 无需认证 + .anyRequest() // 所有请求 + .authenticated() // 都需要认证 + .and().csrf().disable(); + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/UserDetailService.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/UserDetailService.java new file mode 100644 index 0000000..58992aa --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/security/browser/UserDetailService.java @@ -0,0 +1,32 @@ +package cc.mrbird.security.browser; + +import cc.mrbird.domain.MyUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class UserDetailService implements UserDetailsService { + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + // 模拟一个用户,替代数据库获取逻辑 + MyUser user = new MyUser(); + user.setUserName(username); + user.setPassword(this.passwordEncoder.encode("123456")); + // 输出加密后的密码 + System.out.println(user.getPassword()); + + return new User(username, user.getPassword(), user.isEnabled(), + user.isAccountNonExpired(), user.isCredentialsNonExpired(), + user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/BrowserSecurityController.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/BrowserSecurityController.java new file mode 100644 index 0000000..b198589 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/BrowserSecurityController.java @@ -0,0 +1,39 @@ +package cc.mrbird.web.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author MrBird + */ +@RestController +public class BrowserSecurityController { + + private RequestCache requestCache = new HttpSessionRequestCache(); + + private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); + + @GetMapping("/authentication/require") + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public String requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException { + SavedRequest savedRequest = requestCache.getRequest(request, response); + if (savedRequest != null) { + String targetUrl = savedRequest.getRedirectUrl(); + if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) + redirectStrategy.sendRedirect(request, response, "/login.html"); + } + return "访问的资源需要身份认证!"; + } +} diff --git a/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/TestController.java b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/TestController.java new file mode 100644 index 0000000..b677e61 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/java/cc/mrbird/web/controller/TestController.java @@ -0,0 +1,20 @@ +package cc.mrbird.web.controller; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class TestController { + @GetMapping("hello") + public String hello() { + return "hello spring security"; + } + + @GetMapping("index") + public Object index(Authentication authentication) { + // return SecurityContextHolder.getContext().getAuthentication(); + return authentication; + } +} diff --git a/35.Spring-Security-Authentication/src/main/resources/application.yml b/35.Spring-Security-Authentication/src/main/resources/application.yml new file mode 100644 index 0000000..a618ee1 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/resources/application.yml @@ -0,0 +1,3 @@ +security: + basic: + enabled: true \ No newline at end of file diff --git a/35.Spring-Security-Authentication/src/main/resources/resources/css/login.css b/35.Spring-Security-Authentication/src/main/resources/resources/css/login.css new file mode 100644 index 0000000..52d1699 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/resources/resources/css/login.css @@ -0,0 +1,97 @@ +.login-page { + width: 360px; + padding: 8% 0 0; + margin: auto; +} +.form { + position: relative; + z-index: 1; + background: #ffffff; + max-width: 360px; + margin: 0 auto 100px; + padding: 45px; + text-align: center; + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); +} +.form input { + outline: 0; + background: #f2f2f2; + width: 100%; + border: 0; + margin: 0 0 15px; + padding: 15px; + box-sizing: border-box; + font-size: 14px; +} +.form button { + text-transform: uppercase; + outline: 0; + background: #4caf50; + width: 100%; + border: 0; + padding: 15px; + color: #ffffff; + font-size: 14px; + -webkit-transition: all 0.3 ease; + transition: all 0.3 ease; + cursor: pointer; +} +.form button:hover, +.form button:active, +.form button:focus { + background: #43a047; +} +.form .message { + margin: 15px 0 0; + color: #b3b3b3; + font-size: 12px; +} +.form .message a { + color: #4caf50; + text-decoration: none; +} +.form .register-form { + display: none; +} +.container { + position: relative; + z-index: 1; + max-width: 300px; + margin: 0 auto; +} +.container:before, +.container:after { + content: ""; + display: block; + clear: both; +} +.container .info { + margin: 50px auto; + text-align: center; +} +.container .info h1 { + margin: 0 0 15px; + padding: 0; + font-size: 36px; + font-weight: 300; + color: #1a1a1a; +} +.container .info span { + color: #4d4d4d; + font-size: 12px; +} +.container .info span a { + color: #000000; + text-decoration: none; +} +.container .info span .fa { + color: #ef3b3a; +} +body { + background: #76b852; /* fallback for old browsers */ + background: -webkit-linear-gradient(right, #76b852, #8dc26f); + background: -moz-linear-gradient(right, #76b852, #8dc26f); + background: -o-linear-gradient(right, #76b852, #8dc26f); + background: linear-gradient(to left, #76b852, #8dc26f); + font-family: Lato,"PingFang SC","Microsoft YaHei",sans-serif; +} diff --git a/35.Spring-Security-Authentication/src/main/resources/resources/login.html b/35.Spring-Security-Authentication/src/main/resources/resources/login.html new file mode 100644 index 0000000..dc0ff80 --- /dev/null +++ b/35.Spring-Security-Authentication/src/main/resources/resources/login.html @@ -0,0 +1,18 @@ + + + + + 登录 + + + +
+
+

账户登录

+ + + +
+
+ + \ No newline at end of file