Initial commit
This commit is contained in:
		
							
								
								
									
										38
									
								
								common/spring-security/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								common/spring-security/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
target/
 | 
			
		||||
!.mvn/wrapper/maven-wrapper.jar
 | 
			
		||||
!**/src/main/**/target/
 | 
			
		||||
!**/src/test/**/target/
 | 
			
		||||
 | 
			
		||||
### IntelliJ IDEA ###
 | 
			
		||||
.idea/modules.xml
 | 
			
		||||
.idea/jarRepositories.xml
 | 
			
		||||
.idea/compiler.xml
 | 
			
		||||
.idea/libraries/
 | 
			
		||||
*.iws
 | 
			
		||||
*.iml
 | 
			
		||||
*.ipr
 | 
			
		||||
 | 
			
		||||
### Eclipse ###
 | 
			
		||||
.apt_generated
 | 
			
		||||
.classpath
 | 
			
		||||
.factorypath
 | 
			
		||||
.project
 | 
			
		||||
.settings
 | 
			
		||||
.springBeans
 | 
			
		||||
.sts4-cache
 | 
			
		||||
 | 
			
		||||
### NetBeans ###
 | 
			
		||||
/nbproject/private/
 | 
			
		||||
/nbbuild/
 | 
			
		||||
/dist/
 | 
			
		||||
/nbdist/
 | 
			
		||||
/.nb-gradle/
 | 
			
		||||
build/
 | 
			
		||||
!**/src/main/**/build/
 | 
			
		||||
!**/src/test/**/build/
 | 
			
		||||
 | 
			
		||||
### VS Code ###
 | 
			
		||||
.vscode/
 | 
			
		||||
 | 
			
		||||
### Mac OS ###
 | 
			
		||||
.DS_Store
 | 
			
		||||
							
								
								
									
										42
									
								
								common/spring-security/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								common/spring-security/pom.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>com.atguigu</groupId>
 | 
			
		||||
        <artifactId>guigu-oa-parent</artifactId>
 | 
			
		||||
        <version>1.0-SNAPSHOT</version>
 | 
			
		||||
        <relativePath>../../pom.xml</relativePath>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <artifactId>spring-security</artifactId>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <maven.compiler.source>8</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>8</maven.compiler.target>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
    </properties>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.atguigu</groupId>
 | 
			
		||||
            <artifactId>common-util</artifactId>
 | 
			
		||||
            <version>1.0-SNAPSHOT</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.atguigu</groupId>
 | 
			
		||||
            <artifactId>model</artifactId>
 | 
			
		||||
            <version>1.0-SNAPSHOT</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- Spring Security依赖 -->
 | 
			
		||||
        <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>
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
package com.atguigu.security.config;
 | 
			
		||||
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 | 
			
		||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: WebSecurityConfig
 | 
			
		||||
 * Package: com.atguigu.security.config
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 22:47
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
//@EnableWebSecurity是开启SpringSecurity的默认行为
 | 
			
		||||
@EnableWebSecurity
 | 
			
		||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
package com.atguigu.security.custom;
 | 
			
		||||
 | 
			
		||||
import com.atguigu.common.utils.MD5;
 | 
			
		||||
import org.springframework.security.crypto.password.PasswordEncoder;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: CustomMd5PasswordEncoder
 | 
			
		||||
 * Package: com.atguigu.security.custom
 | 
			
		||||
 * 密码处理
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 23:23
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class CustomMd5PasswordEncoder implements PasswordEncoder {
 | 
			
		||||
 | 
			
		||||
    public String encode(CharSequence rawPassword) {
 | 
			
		||||
        return MD5.encrypt(rawPassword.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
 | 
			
		||||
        return encodedPassword.equals(MD5.encrypt(rawPassword.toString()));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
package com.atguigu.security.custom;
 | 
			
		||||
 | 
			
		||||
import com.atguigu.model.system.SysUser;
 | 
			
		||||
import org.springframework.security.core.GrantedAuthority;
 | 
			
		||||
import org.springframework.security.core.userdetails.User;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: CustomUser
 | 
			
		||||
 * Package: com.atguigu.security.custom
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 23:24
 | 
			
		||||
 */
 | 
			
		||||
public class CustomUser extends User {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 我们自己的用户实体对象,要调取用户信息时直接获取这个实体对象。(这里我就不写get/set方法了)
 | 
			
		||||
     */
 | 
			
		||||
    private SysUser sysUser;
 | 
			
		||||
 | 
			
		||||
    public CustomUser(SysUser sysUser, Collection<? extends GrantedAuthority> authorities) {
 | 
			
		||||
        super(sysUser.getUsername(), sysUser.getPassword(), authorities);
 | 
			
		||||
        this.sysUser = sysUser;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SysUser getSysUser() {
 | 
			
		||||
        return sysUser;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSysUser(SysUser sysUser) {
 | 
			
		||||
        this.sysUser = sysUser;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
package com.atguigu.security.custom;
 | 
			
		||||
 | 
			
		||||
import org.springframework.security.core.userdetails.UserDetails;
 | 
			
		||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: UserDetailsService
 | 
			
		||||
 * Package: com.atguigu.security.custom
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 23:28
 | 
			
		||||
 */
 | 
			
		||||
public interface UserDetailsService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据用户名获取用户对象(获取不到直接抛异常)
 | 
			
		||||
     *
 | 
			
		||||
     * @param username
 | 
			
		||||
     * @return
 | 
			
		||||
     * @throws UsernameNotFoundException
 | 
			
		||||
     */
 | 
			
		||||
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
package com.atguigu.security.filter;
 | 
			
		||||
 | 
			
		||||
import com.atguigu.common.jwt.JwtHelper;
 | 
			
		||||
import com.atguigu.common.result.Result;
 | 
			
		||||
import com.atguigu.common.result.ResultCodeEnum;
 | 
			
		||||
import com.atguigu.common.utils.ResponseUtil;
 | 
			
		||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.context.SecurityContextHolder;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.filter.OncePerRequestFilter;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.FilterChain;
 | 
			
		||||
import javax.servlet.ServletException;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: TokenAuthenticationFilter
 | 
			
		||||
 * Package: com.atguigu.security.custom.filter
 | 
			
		||||
 * 认证解析token过滤器
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 23:45
 | 
			
		||||
 */
 | 
			
		||||
public class TokenAuthenticationFilter extends OncePerRequestFilter {
 | 
			
		||||
 | 
			
		||||
    public TokenAuthenticationFilter() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
 | 
			
		||||
        logger.info("uri:" + request.getRequestURI());
 | 
			
		||||
        //如果是登录接口,直接放行
 | 
			
		||||
        if ("/admin/system/index/login".equals(request.getRequestURI())) {
 | 
			
		||||
            chain.doFilter(request, response);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
 | 
			
		||||
        if (null != authentication) {
 | 
			
		||||
            SecurityContextHolder.getContext().setAuthentication(authentication);
 | 
			
		||||
            chain.doFilter(request, response);
 | 
			
		||||
        } else {
 | 
			
		||||
            ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_ERROR));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
 | 
			
		||||
        // token置于header里
 | 
			
		||||
        String token = request.getHeader("token");
 | 
			
		||||
        logger.info("token:" + token);
 | 
			
		||||
        if (!StringUtils.isEmpty(token)) {
 | 
			
		||||
            String useruame = JwtHelper.getUsername(token);
 | 
			
		||||
            logger.info("useruame:" + useruame);
 | 
			
		||||
            if (!StringUtils.isEmpty(useruame)) {
 | 
			
		||||
                return new UsernamePasswordAuthenticationToken(useruame, null, Collections.emptyList());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,90 @@
 | 
			
		||||
package com.atguigu.security.filter;
 | 
			
		||||
 | 
			
		||||
import com.atguigu.common.jwt.JwtHelper;
 | 
			
		||||
import com.atguigu.common.result.Result;
 | 
			
		||||
import com.atguigu.common.result.ResultCodeEnum;
 | 
			
		||||
import com.atguigu.common.utils.ResponseUtil;
 | 
			
		||||
import com.atguigu.security.custom.CustomUser;
 | 
			
		||||
import com.atguigu.vo.system.LoginVo;
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import org.springframework.security.authentication.AuthenticationManager;
 | 
			
		||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.AuthenticationException;
 | 
			
		||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 | 
			
		||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.FilterChain;
 | 
			
		||||
import javax.servlet.ServletException;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClassName: TokenLoginFilter
 | 
			
		||||
 * Package: com.atguigu.security.custom.filter
 | 
			
		||||
 * 登录过滤器,继承UsernamePasswordAuthenticationFilter,对用户名密码进行登录校验
 | 
			
		||||
 *
 | 
			
		||||
 * @author yovinchen
 | 
			
		||||
 * @Create 2023/6/10 23:37
 | 
			
		||||
 */
 | 
			
		||||
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
 | 
			
		||||
 | 
			
		||||
    // 构造方法
 | 
			
		||||
    public TokenLoginFilter(AuthenticationManager authenticationManager) {
 | 
			
		||||
        this.setAuthenticationManager(authenticationManager);
 | 
			
		||||
        this.setPostOnly(false);
 | 
			
		||||
        //指定登录接口及提交方式,可以指定任意路径
 | 
			
		||||
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/index/login", "POST"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 登录认证过程
 | 
			
		||||
    // 获取输入的用户名和密码,调用方法认证
 | 
			
		||||
    @Override
 | 
			
		||||
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
 | 
			
		||||
            throws AuthenticationException {
 | 
			
		||||
        try {
 | 
			
		||||
            // 获取用户信息
 | 
			
		||||
            LoginVo loginVo = new ObjectMapper().readValue(req.getInputStream(), LoginVo.class);
 | 
			
		||||
 | 
			
		||||
            //封装对象
 | 
			
		||||
            Authentication authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
 | 
			
		||||
 | 
			
		||||
            //调用方法
 | 
			
		||||
            return this.getAuthenticationManager().authenticate(authenticationToken);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 认证成功调用的方法
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
 | 
			
		||||
                                            Authentication auth) throws IOException, ServletException {
 | 
			
		||||
        // 获取当前用户
 | 
			
		||||
        CustomUser customUser = (CustomUser) auth.getPrincipal();
 | 
			
		||||
 | 
			
		||||
        // 生成token
 | 
			
		||||
        String token = JwtHelper.createToken(customUser.getSysUser().getId(), customUser.getSysUser().getUsername());
 | 
			
		||||
 | 
			
		||||
        // 返回
 | 
			
		||||
        Map<String, Object> map = new HashMap<>();
 | 
			
		||||
        map.put("token", token);
 | 
			
		||||
        ResponseUtil.out(response, Result.ok(map));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 认证失败调用的方法
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
 | 
			
		||||
                                              AuthenticationException e) throws IOException, ServletException {
 | 
			
		||||
 | 
			
		||||
        if (e.getCause() instanceof RuntimeException) {
 | 
			
		||||
            ResponseUtil.out(response, Result.build(null, ResultCodeEnum.DATA_ERROR));
 | 
			
		||||
        } else {
 | 
			
		||||
            ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_AUTH));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user