前言
本篇博客主要是分享,使用SpringSecurity開發基於表單的認證(一)
一、SpringSecurity核心功能
- 認證(你是誰)
1.實現用戶名+密碼
2.實現手機號+短信認證 - 授權(能幹什麼)
- 攻擊防護(防止僞造身份)
package com.zcw.security.browser;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.stereotype.Component;
/**
* @ClassName : BrowserSecurityConfig
* @Description :適配器類
* @Author : Zhaocunwei
* @Date: 2020-06-18 17:43
*/
@Component
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//表單登錄
http.formLogin()
.and()
//授權
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
- 啓動項目:
- 測試:
二、自定義用戶認證邏輯
- 處理用戶信息獲取邏輯
package com.zcw.security.browser;
import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;
/**
* @ClassName : MyUserDetailsService
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-18 18:31
*/
@Component
@Slf4j
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("登錄用戶名:"+username);
return new User(username,
//在數據庫中存的密碼
"123456",
//數據庫中權限
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
- 測試:
密碼隨便輸入:
輸入正確的密碼:
- 處理用戶校驗邏輯
測試:
- 處理密碼加密解密
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
測試:
正確輸入:123456,兩次發現加鹽驗證:
三、個性化用戶認證流程
- 自定義登錄頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<h2>標準登錄頁面</h2>
<h3>表單登錄</h3>
<form action="/authentication/form" method="post">
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><button type="submit">登錄</button></td>
</tr>
</table>
</form>
</body>
</html>
- 自定義登錄成功處理
package com.zcw.security.browser.support;
import lombok.Data;
/**
* @ClassName : SimpleResponse
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-19 13:41
*/
@Data
public class SimpleResponse {
public SimpleResponse(Object content){
this.content = content;
}
private Object content;
}
創建如圖所示幾個類:
package com.zcw.security.core.properties;
import lombok.Data;
/**
* @ClassName : BrowserProperties
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-19 13:55
*/
@Data
public class BrowserProperties {
private String loginPage;
}
package com.zcw.security.core.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @ClassName : SecurityProperties
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-19 13:54
*/
@ConfigurationProperties(prefix = "zcw.security")
@Data
public class SecurityProperties {
private BrowserProperties browserProperties = new BrowserProperties();
}
package com.zcw.security.core;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName : SecurityCoreConfig
* @Description : 配置類
* @Author : Zhaocunwei
* @Date: 2020-06-19 13:59
*/
@Configuration
@EnableConfigurationProperties(SecurityCoreConfig.class)//使我們的配置類生效
public class SecurityCoreConfig {
}
- 配置默認數據,
- 測試:
項目啓動報錯:
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3068b369: startup date [Fri Jun 19 14:10:04 CST 2020]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@6a47b187
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:427) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:999) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:958) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:750) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at com.zcw.DemoApplication.main(DemoApplication.java:20) [classes/:na]
2020-06-19 14:10:07.772 ERROR 18616 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3068b369: startup date [Fri Jun 19 14:10:04 CST 2020]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@6a47b187
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:414) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.destroySingletons(FactoryBeanRegistrySupport.java:230) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968) [spring-beans-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1030) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1006) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:958) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:750) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at com.zcw.DemoApplication.main(DemoApplication.java:20) [classes/:na]
Not registered via @EnableConfigurationProperties or marked as Spring component
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
- 感覺還是jar包衝突了,需要解決:
還是沒解決,不是jar包的問題:
進行打包時,出現錯誤,解決:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.3.RELEASE:repackage (default) on project zcw-securit
y-demo: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.3.3.RELEASE:repackage failed: Unable to find a sing
le main class from the following candidates [com.zcw.DemoApplication, com.zcw.wiremock.MockServer] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <args> -rf :zcw-security-demo
連續清了三遍:
mvn clean
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>