SpringBoot+SpringSecurity 실제 데이터 기반 인증 실현

(1)개술
Spring Security 는 기능 이 강하 고 고도 로 맞 춤 형 인증 과 방문 제어 프레임 워 크 로 Spring Security 는 주로 두 가지 일 을 하고 인증,권한 을 부여 합 니 다.저 는 예전 에 SpringSecurity 에 관 한 블 로 그 를 쓴 적 이 있 지만 그 당시 에 mock 데 이 터 를 바탕 으로 하 는 사례 만 소 개 했 을 뿐 이번 호 에 서 는 실제 데 이 터 를 바탕 으로 하 는 인증 권한 수여 실현 을 소개 합 니 다.
(2)전기 프로젝트 구축
SpringSecurity 를 더욱 잘 보 여주 기 위해 서 우 리 는 먼저 간단 한 웹 프로젝트 를 만 들 었 다.thymeleaf 의존 도입

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
로그 인 페이지,첫 페이지 를 새로 만 들 고 여러 등급 의 전시 페이지 를 보 여 줍 니 다.
login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>   </title>
</head>
<body>
<div>
    <form>
        <h2>   </h2>
        <input type="text" id="username" placeholder="username">
        <input type="password" id="password" placeholder="password">
        <button type="button">  </button>
    </form>
</div>
</body>
</html>
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>  </title>
</head>
<body>
<div>
    <h2>  </h2>
    <a href="/login" rel="external nofollow" >  </a>
    <div style="overflow: hidden">
        <div style="float: left;margin-left: 20px">
            <h3>level1</h3>
            <a href="/level1/1" rel="external nofollow" >level-1-1</a>
            <hr>
            <a href="/level1/2" rel="external nofollow" >level-1-2</a>
        </div>
        <div style="float: left;margin-left: 20px">
            <h3>level2</h3>
            <a href="/level2/1" rel="external nofollow" >level-2-1</a>
            <hr>
            <a href="/level2/2" rel="external nofollow" >level-2-2</a>
        </div>
        <div style="float: left;margin-left: 20px">
            <h3>level3</h3>
            <a href="/level3/1" rel="external nofollow" >level-3-1</a>
            <hr>
            <a href="/level3/2" rel="external nofollow" >level-3-2</a>
        </div>
    </div>
</div>
</body>
</html>
그리고 몇 개의 서로 다른 등급 의 페이지 가 있 습 니 다.
在这里插入图片描述
각각 body 에 자신 이 대응 하 는 번 호 를 적어 라.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
level-1-1
</body>
</html>
마지막 으로 controller 를 만들어 서 요청 을 받 습 니 다:

@Controller
public class RouteController {

    @RequestMapping({"/","/index"})
    public String index(){
        return "index";
    }

    @RequestMapping("/login")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id")String id){
        return "level1/"+id;
    }
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id")String id){
        return "level2/"+id;
    }
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id")String id){
        return "level3/"+id;
    }
}
최종 효 과 는 다음 과 같다.
在这里插入图片描述
최종 적 으로 등급 이 다른 level 페이지 는 서로 다른 권한 에 따라 이동 합 니 다.
在这里插入图片描述
배경 은 Mybatis 와 Mysql 데이터 베 이 스 를 기반 으로 이 루어 집 니 다.따라서 저 희 는 SpringSecurity 의 의존 도 를 도입 하 는 것 외 에 Mybatis 관련 의존 도 를 도입 해 야 합 니 다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>
프로필 에 데이터 원본 과 Mybatis 설정 을 추가 합 니 다.

spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis.mapper-locations=classpath:mapper/*.xml
(3)인증 과 권한 수여 의 실현
3.1 표 구조 디자인
인증 과 권한 수 여 는 표 디자인 에 있어 두 개의 표 안에 나 누 어야 한다.한 표 는 사용자 정 보 를 암호 등 을 포함 하고 다른 표 는 권한 수여 정 보 를 저장 하 며 한 표 는 사용자 와 권한 수여 간 의 관 계 를 구축 하고 최종 표 구 조 를 제시 해 야 한다.

CREATE TABLE `roles` (
  `id` int(4) NOT NULL,
  `rolename` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `sysuser` (
  `id` int(4) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `user_role` (
  `id` int(4) NOT NULL,
  `user_id` int(4) DEFAULT NULL,
  `role_id` int(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
다음은 이 세 장의 표 의 실체 클래스,Mapper 인터페이스 와 xml 파일 을 대상 으로 코드 를 보지 않 고 사용자 이름 을 통 해 사용자 와 관련 권한 을 찾 는 작업 을 실현 할 수 있 습 니 다.

@Data
public class Roles {
    private Integer id;
    private String roleName;
}

@Data
public class SysUser {
    private Integer id;
    private String userName;
    private String password;
    private List<Roles> roles;
}
Mapper 인터페이스:

public interface UserMapper {
    public SysUser getUserByUserName(@Param("userName") String userName);
}
xml 구현:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.javayz.springsecurity.mapper.UserMapper">
    <resultMap id="userMap" type="com.javayz.springsecurity.entity.SysUser">
        <id property="id" column="ID"/>
        <result property="userName" column="username"/>
        <result property="password" column="password"/>
        <collection property="roles" ofType="com.javayz.springsecurity.entity.Roles">
            <result column="name" property="roleName"/>
        </collection>
    </resultMap>
    <select id="getUserByUserName" parameterType="String"  resultMap="userMap">
        select sysuser.*,roles.rolename
        from sysuser
        LEFT JOIN user_role on sysuser.id= user_role.user_id
        LEFT JOIN roles on user_role.role_id=roles.id
        where username= #{userName}
    </select>
</mapper>
3.2 인증 과정
SpringSecurity 의 인증 과정 은 이 렇 습 니 다.먼저 사용자 이름 이나 다른 유일한 ID 를 통 해 데이터베이스 에서 이 사용 자 를 찾 고 사용자 의 비밀 번 호 는 비대 칭 암호 화 방식 으로 저 장 됩 니 다.사용 자 를 가 져 온 후 프론트 데스크 에 들 어 온 비밀 번 호 를 암호 화한 후 데이터베이스 에 암호 화 된 필드 와 비교 하여 인증 을 통과 합 니 다.
이 과정 에서 첫 번 째 단 계 는 사용자 이름 을 통 해 사용 자 를 찾 는 작업 은 Service 서 비 스 를 통 해 이 루어 져 야 하 며,이 Service 서 비 스 는 SpringSecurity 의 User Details Service 인 터 페 이 스 를 계승 해 야 합 니 다.이 인 터 페 이 스 는 SpringSecurity 의 User 대상 을 되 돌려 줍 니 다.

@Service
public class UserService implements UserDetailsService {

    @Resource
    private UserMapper userMapper;
    //              
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        SysUser sysUser = userMapper.getUserByUserName(s);
        if (sysUser!=null){
            List<GrantedAuthority> roles=new ArrayList<>();
            sysUser.getRoles().stream().forEach(x->{
                roles.add(new SimpleGrantedAuthority(x.getRoleName()));
            });
            return new User(sysUser.getUserName(),sysUser.getPassword(),roles);
        }
        throw new UsernameNotFoundException("     ");
    }
}
3.3 보안 차단 설정
위의 절차 가 완 료 된 후에 Security 를 설정 하기 시 작 했 습 니 다.설정 방법 인 Security Config 를 쓰 십시오.코드 차원 이 간단 합 니 다.인증 은 userService 대상 에 들 어가 면 데이터 베이스 에서 꺼 낸 비밀번호 와 전단 에서 전 달 된 비밀 번 호 를 자동 으로 대조 합 니 다.또한 userService 에 roles 집합 이 들 어 갔 고 권한 수여 처 에 서로 다른 페이지 에 서로 다른 권한 을 부여 하면 됩 니 다.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;
    //  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //         ,level             
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //           ,       /login
        http.formLogin();
    }

    //  
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());

    }
}
3.4 기타 주의 점
제 가 인증 할 때 사용 하 는 암호 화 방식 은 BCryptPasswordEncoder 이기 때문에 데이터베이스 에 저 장 된 암호 도 암호 화 되 어야 합 니 다.자주 사용 하 는 방식 은 등록 할 때 같은 방식 으로 비밀 번 호 를 암호 화하 여 데이터베이스 에 저장 하 는 것 입 니 다.

String password="xxx";
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode=bCryptPasswordEncoder.encode(password);
(4)총화
SpringSecurity 는 이런 방식 외 에 도 통합 JWT,Oauth 2 등 을 지원 한다.나중에 계속 업데이트 하 겠 습 니 다.저 는 물고기 새끼 입 니 다.다음 에 뵙 겠 습 니 다.
여기 서 SpringBoot+SpringSecurity 가 실제 데 이 터 를 바탕 으로 하 는 권한 수여 인증 을 실현 하 는 것 에 관 한 글 을 소개 합 니 다.더 많은 SpringBoot+SpringSecurity 권한 수여 인증 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 십시오.앞으로 저 희 를 많이 지지 해 주시 기 바 랍 니 다!

좋은 웹페이지 즐겨찾기