Spring Security.ch2

이호영·2022년 5월 11일
0

SpringSecurity

목록 보기
2/6
@RestController
public class HomeController {

    @RequestMapping("/")
    public String index(){
        return "홈페이지";
    }

기본적인 코드를 작성하여 실행하면 username과 password를 입력하는 화면이 사용자에게 보여진다.
실행하였을 때 Spring에서 제공하는 passoword는 어렵기 때문에
application.yml에서 설정하면 쉽게 인증받을 수 있다.

spring:
  security:
    user:
      name: user1
      password: 1111
      roles: USER

인증정보를 보고싶을 때

    @RequestMapping("/auth")
    public Authentication auth(){
        return SecurityContextHolder.getContext().getAuthentication();
    }

코드를 사용하여 서버를 재실행 하여 들어가면

{
"authorities":[
{
"authority":"ROLE_USER"
	}
],
"details":{
"remoteAddress":"127.0.0.1",
"sessionId":"659EBB55CAC42A49EBA2E8F018C2B8D7"
},
"authenticated":true,
"principal":{
"password":null,
"username":"user1",
"authorities":[
{
"authority":"ROLE_USER"
	}
],
"accountNonExpired":true,
"accountNonLocked":true,
"credentialsNonExpired":true,
"enabled":true
	},
"credentials":null,
"name":"user1"
}

이러한 인증정보를 가지고 사용자가 접근한것을 알수있다.

user와 admin의 개인정보에 해당되는 리소스를 확인해보자

@PreAuthorize("hasAnyAuthority('ROLE_USER')")
    @RequestMapping("/user")
    public SecurityMessage user() {
        return SecurityMessage.builder()
                .auth(SecurityContextHolder.getContext().getAuthentication())
                .message("User 정보")
                .build(); //user의 개인정보를 보여줌
    }

    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')")
    @RequestMapping("/admin")
    public SecurityMessage admin() {
        return SecurityMessage.builder()
                .auth(SecurityContextHolder.getContext().getAuthentication())
                .message("admin 정보")
                .build(); //admin의 정보를 보여줌
    }

이렇게 실행되면 로그인을 하게되면 user,admin의 정보를 모두 보는것이 가능해저서 정보가 탈취된다.

이러한 현상을 막기위해

package com.example.springsecurity.web.config;

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true) //prepost로 권한 확인
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
}

코드를 작성하여 user가 admin 정보에 접근하려하면
403(Forbidden)에러가 발생한다.
여기서 application.yml에는 사용자를 한명만 설정할 수 있기 때문에 추가로 admin을 등록하기 위한 코드를 작성한다.

package com.example.springsecurity.web.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true) //prepost로 권한 확인
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser(User.builder()
                .username("user2")
                .password(passwordEncoder().encode("2222"))
                .roles("USER")
                ).withUser(User.builder()
                .username("admin")
                .password(passwordEncoder().encode("3333"))
                .roles("ADMIN"));
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

password를 인코딩 해주지않으면 오류가 발생하므로 주의해야 한다.
이렇게되면 또 하나의 문제점이 발생한다.
user1은 로그인을 하지 못한다. 왜냐하면 user에 대한 authentication provider를 추가하면 application.yml의 설정은 더 이상 사용되지 아니한다.

지금까지는 로그인을 해야만 홈페이지가 보이지만 모든 사람들에게
홈페이지는 보여주고 싶다면

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

코드를 추가하면 된다

0개의 댓글