环境搭建
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0" xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" >
< modelVersion> 4.0.0</ modelVersion>
< groupId> com.chauncy</ groupId>
< artifactId> spring-security-demom</ artifactId>
< version> 0.0.1-SNAPSHOT</ version>
< name> spring-security-demom</ name>
< description> Demo project for Spring Boot</ description>
< properties>
< java.version> 1.8</ java.version>
< project.build.sourceEncoding> UTF-8</ project.build.sourceEncoding>
< project.reporting.outputEncoding> UTF-8</ project.reporting.outputEncoding>
< spring-boot.version> 2.3.7.RELEASE</ spring-boot.version>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-security</ artifactId>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-web</ artifactId>
</ dependency>
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.4.2</ version>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
< scope> runtime</ scope>
</ dependency>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-starter-test</ artifactId>
< scope> test</ scope>
< exclusions>
< exclusion>
< groupId> org.junit.vintage</ groupId>
< artifactId> junit-vintage-engine</ artifactId>
</ exclusion>
</ exclusions>
</ dependency>
< dependency>
< groupId> org.springframework.security</ groupId>
< artifactId> spring-security-test</ artifactId>
< scope> test</ scope>
</ dependency>
</ dependencies>
< dependencyManagement>
< dependencies>
< dependency>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-dependencies</ artifactId>
< version> ${spring-boot.version}</ version>
< type> pom</ type>
< scope> import</ scope>
</ dependency>
</ dependencies>
</ dependencyManagement>
< build>
< plugins>
< plugin>
< groupId> org.apache.maven.plugins</ groupId>
< artifactId> maven-compiler-plugin</ artifactId>
< version> 3.8.1</ version>
< configuration>
< source> 1.8</ source>
< target> 1.8</ target>
< encoding> UTF-8</ encoding>
</ configuration>
</ plugin>
< plugin>
< groupId> org.springframework.boot</ groupId>
< artifactId> spring-boot-maven-plugin</ artifactId>
< version> 2.3.7.RELEASE</ version>
< configuration>
< mainClass> com.chauncy.SpringSecurityDemomApplication</ mainClass>
</ configuration>
< executions>
< execution>
< id> repackage</ id>
< goals>
< goal> repackage</ goal>
</ goals>
</ execution>
</ executions>
</ plugin>
</ plugins>
</ build>
</ project>
# 应用名称
spring.application.name=spring-security-demom
# 应用服务 WEB 访问端口
server.port=8080
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://192.168.7.17:3306/chauncy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
# 数据库用户名&密码:
spring.datasource.username=meifute
spring.datasource.password=meifute
基础认证
Security 配置类
package com. chauncy. config ;
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. crypto. bcrypt. BCryptPasswordEncoder ;
import org. springframework. security. crypto. password. PasswordEncoder ;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity ( prePostEnabled = true , securedEnabled = true )
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure ( AuthenticationManagerBuilder auth) throws Exception {
auth. inMemoryAuthentication ( )
. passwordEncoder ( new BCryptPasswordEncoder ( ) )
. withUser ( "user" ) . password ( new BCryptPasswordEncoder ( ) . encode ( "123" ) ) . authorities ( "USER" )
. and ( )
. withUser ( "admin" ) . password ( new BCryptPasswordEncoder ( ) . encode ( "123" ) ) . authorities ( "ADMIN" , "USER" )
. and ( )
. withUser ( "chauncy" ) . password ( new BCryptPasswordEncoder ( ) . encode ( "123" ) ) . authorities ( "OK" ) ;
}
@Override
protected void configure ( HttpSecurity http) throws Exception {
http. csrf ( ) . disable ( )
. formLogin ( ) . failureUrl ( "/error" ) . failureForwardUrl ( "/login" )
. and ( ) . httpBasic ( )
. and ( ) . authorizeRequests ( )
. antMatchers ( "/img/**" ) . permitAll ( )
. antMatchers ( "/admin/**" ) . hasAuthority ( "ADMIN" )
. antMatchers ( "/**" ) . hasAnyAuthority ( "USER" , "ADMIN" )
. anyRequest ( ) . authenticated ( )
. and ( ) . rememberMe ( ) . tokenValiditySeconds ( 600 ) . key ( "caikey" ) ;
}
@Bean
public PasswordEncoder passwordEncoder ( ) {
return new BCryptPasswordEncoder ( ) ;
}
public static class CustomPasswordEncoder implements PasswordEncoder {
@Override
public String encode ( CharSequence charSequence) {
return charSequence. toString ( ) ;
}
@Override
public boolean matches ( CharSequence charSequence, String s) {
return s. equals ( charSequence. toString ( ) ) ;
}
}
}
controller
package com. chauncy. controller ;
import org. springframework. security. core. GrantedAuthority ;
import org. springframework. security. core. context. SecurityContextHolder ;
import org. springframework. security. core. userdetails. UserDetails ;
import org. springframework. web. bind. annotation. GetMapping ;
import org. springframework. web. bind. annotation. RestController ;
import javax. servlet. http. HttpServletRequest ;
@RestController
public class MainController {
@GetMapping ( "/admin/api/hello" )
public String hello ( HttpServletRequest request) {
System . out. println ( "request.getRemoteUser()用户: " + request. getRemoteUser ( ) ) ;
UserDetails ud = ( UserDetails ) SecurityContextHolder . getContext ( ) . getAuthentication ( ) . getPrincipal ( ) ;
System . out. println ( "SecurityContextHolder用户: " + ud. getUsername ( ) ) ;
System . out. println ( ud. getPassword ( ) ) ;
for ( GrantedAuthority authority : ud. getAuthorities ( ) ) {
System . out. println ( "角色: " + authority) ;
}
return "hello" ;
}
@GetMapping ( "/api/hello" )
public String ww ( HttpServletRequest request) {
System . out. println ( "request.getRemoteUser()用户: " + request. getRemoteUser ( ) ) ;
UserDetails ud = ( UserDetails ) SecurityContextHolder . getContext ( ) . getAuthentication ( ) . getPrincipal ( ) ;
System . out. println ( "SecurityContextHolder用户: " + ud. getUsername ( ) ) ;
System . out. println ( ud. getPassword ( ) ) ;
for ( GrantedAuthority authority : ud. getAuthorities ( ) ) {
System . out. println ( "角色: " + authority) ;
}
return "world" ;
}
@GetMapping ( "/error" )
public String error ( ) {
return "ERROR: 请重新登录!!!" ;
}
}
使用数据库进行认证
CREATE TABLE ` user_sec` (
` id` bigint ( 20 ) NOT NULL ,
` username` varchar ( 20 ) NOT NULL ,
` password` varchar ( 66 ) NOT NULL ,
` roles` varchar ( 255 ) DEFAULT NULL ,
` enabled` tinyint ( 1 ) NOT NULL ,
PRIMARY KEY ( ` id` ) USING BTREE ,
UNIQUE KEY ` indx_user` ( ` username` )
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
package com. chauncy. config ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. beans. factory. annotation. Qualifier ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. security. authentication. dao. DaoAuthenticationProvider ;
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 ;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Qualifier ( "userDetailsServiceImpl" )
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure ( AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider daoAuthProvider = new DaoAuthenticationProvider ( ) ;
daoAuthProvider. setPasswordEncoder ( passwordEncoder ( ) ) ;
daoAuthProvider. setUserDetailsService ( userDetailsService) ;
auth. authenticationProvider ( daoAuthProvider) ;
}
@Override
protected void configure ( HttpSecurity http) throws Exception {
http. csrf ( ) . disable ( )
. formLogin ( ) . failureUrl ( "/error" ) . failureForwardUrl ( "/login" )
. and ( ) . httpBasic ( )
. and ( ) . authorizeRequests ( )
. antMatchers ( "/img/**" ) . permitAll ( )
. antMatchers ( "/admin/**" ) . hasRole ( "ADMIN" )
. antMatchers ( "/**" ) . hasAnyRole ( "USER" , "ADMIN" )
. anyRequest ( ) . authenticated ( )
. and ( ) . rememberMe ( ) . tokenValiditySeconds ( 600 ) . key ( "caikey" ) ;
}
@Bean
public PasswordEncoder passwordEncoder ( ) {
return new BCryptPasswordEncoder ( ) ;
}
public static class CustomPasswordEncoder implements PasswordEncoder {
@Override
public String encode ( CharSequence charSequence) {
return charSequence. toString ( ) ;
}
@Override
public boolean matches ( CharSequence charSequence, String s) {
return s. equals ( charSequence. toString ( ) ) ;
}
}
}
package com. chauncy. service. impl ;
import com. chauncy. entity. UserSec ;
import com. chauncy. service. mapper. UserSecMapper ;
import org. springframework. beans. factory. annotation. Autowired ;
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 ;
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserSecMapper mapper;
@Override
public UserDetails loadUserByUsername ( String username) throws UsernameNotFoundException {
UserSec user = mapper. selectByUsername ( username) ;
return new User ( username, user. getPassword ( ) , AuthorityUtils . createAuthorityList ( user. getRoles ( ) ) ) ;
}
}