OAuth2 개념
OAuth 2.0(Open Authorization 2.0, OAuth2)는 인증을 위한 개방향 표준 프로토콜이다.
이 프로토콜에서는 Third-Party 프로그램에게 리소스 소유자를 대신해 리소스 서버에서 제공하는 자원에 대한
접근 권한을 위임하는 방식으로 작동되며 구글, 페이스북 등 외부 소셜 계정을 기반으로 간편하게 인증하는 기능이다.
OAuth2 제공자
- 구글
- 페이스북
- 카카오
- 네이버
먼저 알아야 할 용어
- Authentication(인증) 인증, 접근 자격이 있는지 검증하는 단계
- Authorization(인가) 자원에 접근할 권할을 부여하고 리소스 접근 권한이 있는 Acess Token을 제공
- Access Token 리소스 서버에게서 정보를 획득할 때 사용되는 토큰으로, 만료 기간이 있는 Token
- Refresh Token Acess Token이 만료 시 재발급 받기 위한 용도로 사용하는 Token
OAuth2.0 권한 부여 방식
1. Authorization Code Grant - 권한 부여 승인 코드 방식
- 권한 부여 승인 요청 시 response_tpye=code, grant_type = authorization_code 로 지정하여 요청하는 방식으로 가장 기본이 되는 방식
- Refrsh Token 사용이 가능함.
- request에 포함된 redirect_url로 Authorization Code를 전달
- Authorization Code는 Authorization Server를 통해 Access Token으로 교환
- Access Token을 사용하여 Reource Server에 접근
2. Implicit Grant - 암묵적 승인 방식
자격증명을 안전하게 저장하기 힘든 클라이언트(ex: javascript)에게 최적화 된 방식으로
response_type = token으로 요청
- 권한 부여 승인 코드 없이 바로 Access Token이 발급 (노출 위험을 방지하기 위해 보통 만료기간을 짧게함.)
- Refresh Token 사용이 불가능함.
- Access Token이 URL로 전달 된다는 단점이 있음(위험)
3. Resource Owner Password Credentials Grant - 자원 소유자 자격증명 승인 방식
- 간단하게 username, password로 Access Token을 받는 방식으로 grant_type = password 로 요청한다
- 클라이언트가 자신의 서비스에서 제공하는 어플리케이션일 경우에만 사용하는 방식.
- Refrsh Token 사용 가능
4. Client Credentials Grant - 클라이언트 자격증명 승인 방식
- 클라이언트의 자격증명만으로 Access Token을 획득하는 방식으로 grant_type = client_credentials 로 요청한다.
- 자격증명을 안전하게 보관할 수 있는 클라이언트에만 사용
- Refresh Token은 사용 불가능
OAuth2 설정 Annotation
@EnableResourceServer
@EnableResourceServer 어노테이션을 추가한 클래스가 만들어지면 기본적으로 모든요청에 대해 인증을 필요로하게 된다.
OAuth 토큰에 의해 보호되고 있는 자원 서버에 대한 설정이다. Sprint OAuth 에서는 자원에대한 보호를 구현하는 Spring Security Filter 를 제공한다. @EnableResourceServer 어노테이션을 붙임으로서 해당 필터를 활성화 할 수 있다.
이 설정에서는 각 리소스 (여기에서는 user 정보) 에 대한 접근 권한을 설정해주고 있다.
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable()
.authorizeRequests()
.antMatchers("/users/**").authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
@EnableAuthorizationServer
인증서버 설정에서는 @EnableAuthorizationServer 어노테이션을 통해 oauth 서버에 필요한 기본설정을 세팅할 수 있다.
클래스에 @EnableAuthorizationServer 어노테이션을 붙이는 것 만으로도 OAuth 관련 endpoints 가 생성된다.
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
...
@EnableAuthorizationServer
@Configuration
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("iamclient")
.secret(passwordEncoder.encode("iamsecret"))
.authorizedGrantTypes("authorization_code", "password", "refresh_token")
.scopes("read", "write")
.accessTokenValiditySeconds(60*60)
.refreshTokenValiditySeconds(6*60*60)
.autoApprove(true);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
이 클래스는 AuthorizationServerConfigurer 를 구현해야 하며, 주요 메소드를 포함한 구현체인 AuthorizationServerConfigurerAdapter 를 상속받으면 편리하다.
설정 내에서는 configure 메소드를 override 하면 되는데, configure 메소드의 파라미터에 따라 다음 세 가지 종류의 설정을 할 수 있다.
- ClientDetailsServiceConfigurer
클라이언트에 대한 설정을 할 수 있다. 클라이언트 정보를 DB 로 관리할 것인지, Inmemory 로 관리할 것인지 등에 대한 설정이나, 클라이언트별로 제공할 scope 나 권한 등을 정의할 수 있다. - AuthorizationServerSecurityConfigurer
토큰 엔드포인트 (/auth/token) 에 대한 보안관련 설정을 할 수 있다. - AuthorizationServerEndpointsConfigurer
인증, 토큰 엔드포인트, 토큰 서비스를 정의할 수 있다.
* 위에서 tokenStore, userDetailsService 등 객체를 빈으로 가져와 설정에 등록되어있다고 가정한다.
참고 사이트
'개발중 > Spring' 카테고리의 다른 글
Spring 프로젝트에서 A DB 와 B DB 커넥션 맺어서 사용하려고 하는데 패키지명과 패키지 구조를 어떻게 잡아야할지 고민이야. (0) | 2023.03.17 |
---|---|
[Spring] 다이나믹 프록시(dynamic Proxy) (0) | 2023.03.04 |
[Spring] CORS 가 뭐야 ? (1) | 2023.02.11 |
Sql Mapper (mybatis) 의 단점 요약 ! (0) | 2023.02.04 |
[Spring] Spring Bean 에 대한 기록 (0) | 2023.02.01 |