복붙노트

[SPRING] Spring 3와 함께 REST에서 로그인 / 로그 아웃

SPRING

Spring 3와 함께 REST에서 로그인 / 로그 아웃

우리는 Spring 3을 사용하여 RESTful 웹 서비스를 개발 중이며 / webservices / login / / / 및 / webservices / logout과 같은 로그인 / 로그 아웃 기능이 필요합니다. 세션은 타임 아웃되거나 다른 웹 서비스의 소비를 허용하기 위해 로그 아웃 될 때까지 컨텍스트에 저장되어야합니다. 세션 정보없이 웹 서비스에 액세스하라는 요청은 거부되어야합니다. 이 시나리오에 대한 최첨단 솔루션을 찾고 있습니다.

나는 실제로 Spring Security 3에서 프로그래밍 방식으로 로그인 한 질문에 대해 아직 답변하지 않은 질문을 부활시키고 있습니다. web.xml에도 필요한 변경 사항을 지정하십시오.

해결법

  1. ==============================

    1.스프링 보안 필터를 완전히 수동으로 정의하는 것이 좋습니다. 그리 어렵지는 않지만 로그인 / 로그 아웃 동작을 완벽하게 제어 할 수 있습니다.

    스프링 보안 필터를 완전히 수동으로 정의하는 것이 좋습니다. 그리 어렵지는 않지만 로그인 / 로그 아웃 동작을 완벽하게 제어 할 수 있습니다.

    우선, 필터 체인 처리를 Spring에 위임하기 위해 표준 web.xml blurb가 필요합니다 (Servlet API 버전 3이 아닌 경우 async-as를 제거하십시오).

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <async-supported>true</async-supported>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>
    
    
    
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    이제 보안 컨텍스트에서 각 경로에 대해 별도로 필터를 정의합니다. 필터는 사용자 인증, 사용자 로그 아웃, 보안 자격 증명 확인 등을 할 수 있습니다.

    <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map path-type="ant">
            <sec:filter-chain pattern="/login" filters="sif,wsFilter"/>
            <sec:filter-chain pattern="/logout" filters="sif,logoutFilter" />
            <sec:filter-chain pattern="/rest/**" filters="sif,fsi"/>
        </sec:filter-chain-map>
    </bean>
    

    위의 XML은 Spring에게 필터 체인을 통해 특정 컨텍스트 관련 URL로 요청을 전달하도록 지시합니다. 필터 체인 중 첫 번째 것은 보안 컨텍스트를 설정하는 것입니다. 'sif'bean이이를 처리합니다.

    <bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
    

    체인의 다음 필터는 이제 보안 컨텍스트 (읽기 : 로그인 / 로그 아웃 사용자)에 데이터를 추가하거나 보안 컨텍스트를 기반으로 액세스 허용 여부를 결정할 수 있습니다.

    로그인 URL의 경우 요청에서 인증 데이터를 읽고 유효성을 검사 한 다음 보안 컨텍스트 (세션에 저장 됨)에 저장하는 필터가 필요합니다.

    <bean id="wsFilter" class="my.own.security.AuthenticationFilter">
      <property name="authenticationManager" ref="authenticationManager"/>
      <property name="authenticationSuccessHandler" ref="myAuthSuccessHandler"/>
      <property name="passwordParameter" value="pass"></property>
      <property name="usernameParameter" value="user"></property>
      <property name="postOnly" value="false"></property>
    

    Spring의 일반적인 UsernamePasswordAuthenticationFilter를 사용할 수는 있지만 필자가 구현 한 것을 사용하는 이유는 필터 체인 처리를 계속하는 것입니다 (기본 구현은 사용자가 성공적인 인증을 받으면 리디렉션되고 필터 체인을 종료한다고 가정 함). 사용자 이름과 비밀번호가 전달 될 때마다 인증을 처리 할 수 ​​있습니다. 그것에 :

    public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    
    @Override
    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
        return ( StringUtils.hasText(obtainUsername(request)) && StringUtils.hasText(obtainPassword(request)) );
    }
    
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
            Authentication authResult) throws IOException, ServletException{
        super.successfulAuthentication(request, response, chain, authResult);
        chain.doFilter(request, response);
    }
    

    HTTP 기본 인증 헤더, 다이제스트 헤더를 사용하는 인증 또는 요청 본문에서 username / pwd 추출과 같은 / login 경로에 대한 필터 구현을 원하는만큼 추가 할 수 있습니다. Spring은 그것을위한 많은 필터를 제공한다.

    기본 리디렉션 전략을 재정의하는 자체 인증 성공 처리기가 있습니다.

    public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    
       @PostConstruct
       public void afterPropertiesSet() {
           setRedirectStrategy(new NoRedirectStrategy());
       }
    
        protected class NoRedirectStrategy implements RedirectStrategy {
    
            @Override
            public void sendRedirect(HttpServletRequest request,
                    HttpServletResponse response, String url) throws IOException {
                // no redirect
    
            }
    
        }
    
    }
    

    로그인 성공 후 사용자가 리디렉션되는 것이 좋습니다 (리디렉션 URL을 사용자 정의 할 수 있으며 문서 확인) 경우 사용자 정의 인증 성공 처리기 (및 사용자 정의 인증 필터)를 가질 필요가 없습니다.

    사용자의 세부 정보를 가져올 책임이있는 인증 관리자를 정의하십시오.

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref="myAuthAuthProvider"/>
    </sec:authentication-manager>
    
     <bean id="myAuthAuthProvider" 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="myUserDetailsImpl"/>
            </bean>
        </property>
    </bean>
    

    여기서 사용자 고유의 Bean 구현을 제공해야합니다.

    로그 아웃 필터 : 보안 컨텍스트 삭제를 담당합니다.

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
            </list>
        </constructor-arg>
    </bean>
    

    일반 인증 항목 :

    <bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <ref bean="roleVoter"/>
            </list>
        </property>
    </bean>
    
    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
    
    <bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>
    

    액세스 제어 필터 (자체 설명 가능) :

    <bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="myAuthenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="securityMetadataSource">
            <sec:filter-invocation-definition-source>
                <sec:intercept-url pattern="/rest/**" access="ROLE_REST"/>
            </sec:filter-invocation-definition-source>
        </property>
    </bean>
    

    또한 메서드에 @Secured 주석을 사용하여 REST 서비스를 보호 할 수 있어야합니다.

    위의 컨텍스트는 기존 REST 서비스 웹 응용 프로그램에서 발췌되었습니다.

    또한 적어도 여기에 구현 된 것 중 가장 많은 것을 재고 SEC 태그를 사용하여 수행 할 수도 있지만, 대부분의 제어를 제공하는 맞춤형 접근 방식을 선호합니다.

    최소한이 일이 시작되기를 바랍니다.

  2. from https://stackoverflow.com/questions/14733418/login-logout-in-rest-with-spring-3 by cc-by-sa and MIT license