programing

Spring Boot 및 Spring Security로 REST API를 보호하는 방법은 무엇입니까?

nasanasas 2020. 10. 22. 08:07
반응형

Spring Boot 및 Spring Security로 REST API를 보호하는 방법은 무엇입니까?


REST API 보안이 널리 언급되는 주제라는 것을 알고 있지만 내 기준을 충족하는 작은 프로토 타입을 만들 수 없습니다 (이러한 기준이 현실적인지 확인해야 함). 리소스를 보호하는 방법과 Spring 보안을 사용하는 방법에는 많은 옵션이 있으므로 내 요구 사항이 현실적인지 명확히해야합니다.

내 요구 사항

  • 토큰 기반 인증 자-사용자는 자격 증명을 제공하고 고유하고 시간이 제한된 액세스 토큰을 얻습니다. 자체 구현에서 토큰 생성, 유효성 확인, 만료를 관리하고 싶습니다.
  • 일부 REST 리소스는 공개되므로 인증 할 필요가 없습니다.
  • 일부 리소스는 관리자 권한이있는 사용자 만 액세스 할 수 있습니다.
  • 모든 사용자에 대한 권한 부여 후에 다른 리소스에 액세스 할 수 있습니다.
  • 기본 인증을 사용하고 싶지 않습니다.
  • Java 코드 구성 (XML 아님)

현재 상태

내 REST API는 매우 잘 작동하지만 이제 보안이 필요합니다. 솔루션을 찾고있을 때 javax.servlet.Filter필터를 만들었습니다 .

  @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
        Account account = accountDao.find(accessToken);

        if (account == null) {    
            throw new UnauthorizedException();    
        }

        chain.doFilter(req, res);

    }

그러나이 솔루션 javax.servlet.filters@ControllerAdviceSpring을 통한 예외 처리에 문제가 있기 때문에 필요에 따라 작동하지 않습니다 servlet dispatcher.

내가 필요한 것

이 기준이 현실적인지 알고 싶고 도움이 필요하면 Spring Security로 REST API 보안을 시작하는 방법을 알고 싶습니다. 많은 튜토리얼 (예 : Spring Data REST + Spring Security )을 읽었 지만 모두 매우 기본적인 구성으로 작동 합니다. 자격 증명을 가진 사용자 는 구성의 메모리저장 되며 DBMS로 작업하고 자체 인증자를 만들어야합니다.

시작하는 방법을 알려주세요.


토큰 기반 인증-사용자는 자격 증명을 제공하고 고유하고 시간이 제한된 액세스 토큰을받습니다. 자체 구현에서 토큰 생성, 유효성 확인, 만료를 관리하고 싶습니다.

실제로 토큰 인증에 필터를 사용하세요.이 경우 가장 좋은 방법입니다.

결국 SpringData를 통해 CRUD를 생성하여 만료 등 토큰의 속성을 관리 할 수 ​​있습니다.

내 토큰 필터는 다음과 같습니다. http://pastebin.com/13WWpLq2

및 토큰 서비스 구현

http://pastebin.com/dUYM555E

일부 REST 리소스는 공개되므로 인증 할 필요가 없습니다.

문제가되지 않습니다. 다음과 같이 Spring 보안 구성을 통해 리소스를 관리 할 수 ​​있습니다. .antMatchers("/rest/blabla/**").permitAll()

일부 리소스는 관리자 권한이있는 사용자 만 액세스 할 수 있습니다.

@Secured수업 에 대한 주석을 살펴보십시오 . 예:

@Controller
@RequestMapping(value = "/adminservice")
@Secured("ROLE_ADMIN")
public class AdminServiceController {

다른 리소스는 모든 사용자에 대한 권한 부여 후에 액세스 할 수 있습니다.

Spring Security 구성으로 돌아가서 다음과 같이 URL을 구성 할 수 있습니다.

    http
            .authorizeRequests()
            .antMatchers("/openforall/**").permitAll()
            .antMatchers("/alsoopen/**").permitAll()
            .anyRequest().authenticated()

기본 인증을 사용하고 싶지 않습니다.

네, 토큰 필터를 통해 사용자가 인증됩니다.

Java 코드 구성 (XML 아님)

위의 단어로 돌아가서를보세요 @EnableWebSecurity. 수업은 다음과 같습니다.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}

구성 방법 을 재정의해야 합니다 . 예를 들어 아래 코드는 매처를 구성하는 방법입니다. 다른 프로젝트에서 가져온 것입니다.

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/assets/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .loginPage("/login")
                .defaultSuccessUrl("/", true)
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
                .logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .and()
                .csrf();
}

Spring 보안은 REST URL에 대한 인증 및 권한 부여에도 매우 유용합니다. 사용자 지정 구현을 지정할 필요가 없습니다.

먼저 아래와 같이 보안 구성에서 restAuthenticationEntryPoint에 대한 entry-point-ref를 지정해야합니다.

 <security:http pattern="/api/**" entry-point-ref="restAuthenticationEntryPoint" use-expressions="true" auto-config="true" create-session="stateless" >

    <security:intercept-url pattern="/api/userList" access="hasRole('ROLE_USER')"/>
    <security:intercept-url pattern="/api/managerList" access="hasRole('ROLE_ADMIN')"/>
    <security:custom-filter ref="preAuthFilter" position="PRE_AUTH_FILTER"/>
</security:http>

restAuthenticationEntryPoint에 대한 구현은 다음과 같습니다.

 @Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

   public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException ) throws IOException {
      response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
   }
}

After this you need to specify RequestHeaderAuthenticationFilter. It contains the RequestHeader key. This is basically used for identifying the user`s authentication. Generally RequestHeader carries this information while making the REST calls. For example consider below code

   <bean id="preAuthFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <property name="principalRequestHeader" value="Authorization"/>
    <property name="authenticationManager" ref="authenticationManager" />
  </bean>

Here,

<property name="principalRequestHeader" value="Authorization"/>

"Authorization" is the the key presented the incoming request. It holds the required user`s authentication information. Also you need to configure the PreAuthenticatedAuthenticationProvider to fulfill our requirement.

   <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
  <bean id="userDetailsServiceWrapper"
      class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
    <property name="userDetailsService" ref="authenticationService"/>
  </bean>
</property>
</bean>

This code will work for securing the REST urls by means of Authentication and authorization without any custom implementations.

For Complete code please find the below link:

https://github.com/srinivas1918/spring-rest-security


I searched this long time too.I am working on a similar project.I found out Spring has a module to implement session via redis. It looks easy and useful. I will add to my project too. Can be helpful:

http://docs.spring.io/spring-session/docs/1.2.1.BUILD-SNAPSHOT/reference/html5/guides/rest.html


To validate REST API there are 2 ways

1 - Basic authentication using default username and password set up in application.properties file

Basic Authentication

2 - Authenticate using database (userDetailsService) with the actual username and password

Advanced Authentication

참고URL : https://stackoverflow.com/questions/32548372/how-to-secure-rest-api-with-spring-boot-and-spring-security

반응형