Programming/Spring Boot

스프링 시큐리티 (스프링 부트 활용 - 10)

흠냐아뤼 2020. 3. 13. 18:05
728x90

1. 스프링 시큐리티

웹 시큐리티

메소드 시큐리티

다양한 인증 방법 지원

 

1) security 의존성 추가

 

바로 security사용이 가능하며, 모든 요청에 인증이 필요함

기본 사용자는 스프링이 생성 (username : user, password : 실행할 때마다 랜덤 값)

스프링 부트가 기본적으로 제공하는 시큐리티는 거의 사용하지 않고, 커스텀마이징 하여 사용함

 

 

2) 시큐리티 커스텀 예제

1. index.html, hello.html 은 로그인 하지 않아도 확인 가능하지만, my.html 은 로그인을 해야 확인 가능

2. 스프링 부트에서 자동으로 만들어주는 user가 아닌, Runner에서 user를 생성

 

예제 계층구조

 

1) 의존성 추가

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

 

2) Controller 작성

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/my")
    public String my() {
        return "my";
    }
}

 

3) index.html, hello.html, my.html 작성

index.html 에서 hello, my 로 이동할 수 있는 웹 페이지

 

4) 스프링 데이터 JPA 설정

4-1) Account 작성

@Entity
public class Account {

    @Id @GeneratedValue
    private Long id;

    private String username;

    private String password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    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;
    }

}

 

4-2) AccountRepository 작성

public interface AccountRepository extends JpaRepository<Account, Long> {
    Optional<Account> findByUsername(String username);
}

 

6) AccountService 작성

@Service
public class AccountService implements UserDetailsService {
    // UserDetailsService 타입의 빈이 등록되어 있어야
    // spring boot가 기본 유저를 등록해주지 않음

    @Autowired
    AccountRepository accountRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    public Account createAccount(String username, String password) {
        Account account = new Account();
        account.setUsername(username);
        account.setPassword(passwordEncoder.encode(password));
        return accountRepository.save(account);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<Account> byUsername = accountRepository.findByUsername(username);
        final Account account = byUsername.orElseThrow(() -> new UsernameNotFoundException(username));
        return new User(account.getUsername(), account.getPassword(), authorities());
    }

    private Collection<? extends GrantedAuthority> authorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    }
}

 

7) SecurityConfig 작성 

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/hello").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .and()
            .httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}

 

8) AccountRunner 작성

@Component
public class AccountRunner implements ApplicationRunner {

    @Autowired
    AccountService accountService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        final Account hongchan = accountService.createAccount("hongchan", "1234");
        System.out.println(hongchan.getUsername() + " " + hongchan.getPassword());
    }
}

 

728x90