-
[OAuth2]Springboot/Security 2019. 12. 17. 15:57
: 표준 인증 프로토콜. 토큰을 사용해 인증을 제공한다.
# 승인타입
- Authorization Code Grant Type : (권한부여코드승인) auth server에 access token을 받아 인증에 이용.
- Implict Grant Type : (암시적 승인) access token을 즉시 반환해 인증에 이용. 응답타입 token
# 순서
1-1) client -> auth server : 권한부여코드 요청 {Client id / Redirect URL / reponse_type(code | token)} 전달
1-2) resource owner로그인 : 권한부여코드(code | token) Redirect URL로 client에게 전달
2-1) client -> auth server : 권한부여코드를 반환, accessToken 요청{client id/secret/redirectUrl/grant_type} 전달
2-2) access token 전달
3-1) client -> resource server : accessToken 으로 API 호출
3-2) 요청 데이터 전달
[Login]
package com.example; import java.security.Principal; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter; import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter; import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.csrf.CookieCsrfTokenRepository; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.filter.CompositeFilter; @SpringBootApplication @RestController @EnableOAuth2Client @EnableAuthorizationServer @Order(200) public class SocialApplication extends WebSecurityConfigurerAdapter { @Autowired OAuth2ClientContext oauth2ClientContext; @RequestMapping({ "/user", "/me" }) public Map<String, String> user(Principal principal) { Map<String, String> map = new LinkedHashMap<>(); map.put("name", principal.getName()); return map; } @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("configure 실행합니다"); http.antMatcher("/**") // 모든요청은 보호됩니다 .authorizeRequests() .antMatchers("/", "/login**", "/webjars/**").permitAll() // 홈페이지,로긴 앤드포인트는 예외 .anyRequest().authenticated() // 그외 요청은 인증사용자가 필요합니다 .and().exceptionHandling() .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")) // 인증안된 사용자는 홈페이지로 리디렉션 .and().logout().logoutSuccessUrl("/").permitAll() .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); ; } @Configuration @EnableResourceServer protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { System.out.println("ResourceServerConfigurer 실행합니다"); http .antMatcher("/me") .authorizeRequests().anyRequest().authenticated(); } } private Filter ssoFilter() { System.out.println("ssofilter 실행합니다"); CompositeFilter filter = new CompositeFilter(); List<Filter> filters = new ArrayList<>(); filters.add(ssoFilter(facebook(), "/login/facebook")); filters.add(ssoFilter(github(), "/login/github")); filter.setFilters(filters); return filter; } private Filter ssoFilter(ClientResources client, String path) { OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(path); OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext); filter.setRestTemplate(template); UserInfoTokenServices tokenServices = new UserInfoTokenServices( client.getResource().getUserInfoUri(), client.getClient().getClientId()); tokenServices.setRestTemplate(template); filter.setTokenServices(tokenServices); return filter; } @Bean public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) { System.out.println("security filter 실행합니다"); FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>(); registration.setFilter(filter); registration.setOrder(-100); return registration; } @Bean @ConfigurationProperties("github") public ClientResources github() { return new ClientResources(); } @Bean @ConfigurationProperties("facebook") public ClientResources facebook() { return new ClientResources(); } public static void main(String[] args) { SpringApplication.run(SocialApplication.class, args); } } class ClientResources { @NestedConfigurationProperty private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails(); @NestedConfigurationProperty private ResourceServerProperties resource = new ResourceServerProperties(); public AuthorizationCodeResourceDetails getClient() { return client; } public ResourceServerProperties getResource() { return resource; } }이걸.. 분리해보자!
'Springboot > Security' 카테고리의 다른 글
[Security] OAuth2 debug (0) 2020.06.15 [Spring Security] (0) 2020.01.18