복붙노트

[SPRING] 봄을 통해 편안하고 인증

SPRING

봄을 통해 편안하고 인증

문제: 우리는 중요한 정보가 들어있는 스프링 MVC 기반의 RESTful API가 있습니다. 이 API는하지만 각 요청과 함께 사용자의 자격 증명 (사용자 / 패스 콤보)를 전송 확보해야하는 것은 바람직하지 않다. 당 REST 지침 (및 내부 비즈니스 요구 사항), 서버는 상태 비 유지해야합니다. API는 매시업 스타일의 접근 방식에서 다른 서버에 의해 소비 될 것이다.

요구 사항 :

우리는 그렇게 희망 누군가가 이미이 문제가 해결했다,이 작품을 만들려고 벽에 우리의 머리를 두드리는 있었어요.

위의 시나리오 감안할 때, 당신은 어떻게이 특정 필요를 해결할 수 있는가?

해결법

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

    1.우리는 솔루션의 작업 정확히 같은 OP 설명, 잘하면 다른 사람이 할 수 사용을 얻을 수 있었다. 여기에 우리가 무슨 짓을했는지 :

    우리는 솔루션의 작업 정확히 같은 OP 설명, 잘하면 다른 사람이 할 수 사용을 얻을 수 있었다. 여기에 우리가 무슨 짓을했는지 :

    그래서 같은 보안 컨텍스트를 설정합니다 :

    <security:http realm="Protected API" use-expressions="true" auto-config="false" create-session="stateless" entry-point-ref="CustomAuthenticationEntryPoint">
        <security:custom-filter ref="authenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER" />
        <security:intercept-url pattern="/authenticate" access="permitAll"/>
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
    </security:http>
    
    <bean id="CustomAuthenticationEntryPoint"
        class="com.demo.api.support.spring.CustomAuthenticationEntryPoint" />
    
    <bean id="authenticationTokenProcessingFilter"
        class="com.demo.api.support.spring.AuthenticationTokenProcessingFilter" >
        <constructor-arg ref="authenticationManager" />
    </bean>
    

    당신이 볼 수 있듯이, 우리는 요청이 우리의 AuthenticationTokenProcessingFilter하여 필터 체인에서 인증되지 않은 경우 기본적으로 그냥 무단으로 401을 반환하는 사용자 지정 AuthenticationEntryPoint를을 만들었습니다.

    CustomAuthenticationEntryPoint :

    public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException {
            response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Authentication token was either missing or invalid." );
        }
    }
    

    AuthenticationTokenProcessingFilter :

    public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
    
        @Autowired UserService userService;
        @Autowired TokenUtils tokenUtils;
        AuthenticationManager authManager;
    
        public AuthenticationTokenProcessingFilter(AuthenticationManager authManager) {
            this.authManager = authManager;
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            @SuppressWarnings("unchecked")
            Map<String, String[]> parms = request.getParameterMap();
    
            if(parms.containsKey("token")) {
                String token = parms.get("token")[0]; // grab the first "token" parameter
    
                // validate the token
                if (tokenUtils.validate(token)) {
                    // determine the user based on the (already validated) token
                    UserDetails userDetails = tokenUtils.getUserFromToken(token);
                    // build an Authentication object with the user's info
                    UsernamePasswordAuthenticationToken authentication = 
                            new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
                    // set the authentication into the SecurityContext
                    SecurityContextHolder.getContext().setAuthentication(authManager.authenticate(authentication));         
                }
            }
            // continue thru the filter chain
            chain.doFilter(request, response);
        }
    }
    

    물론, TokenUtils는 일부 관여 (매우 케이스 별) 코드를 포함하고 쉽게 공유 할 수 없습니다. 여기에 자사의 인터페이스는 다음과 같습니다

    public interface TokenUtils {
        String getToken(UserDetails userDetails);
        String getToken(UserDetails userDetails, Long expiration);
        boolean validate(String token);
        UserDetails getUserFromToken(String token);
    }
    

    즉 좋은 시작에 당신을 하차해야한다. 해피 코딩. :)

  2. ==============================

    2.당신은 다이제스트 액세스 인증을 고려할 수 있습니다. 다음과 같이 기본적으로 프로토콜은 다음과 같습니다

    당신은 다이제스트 액세스 인증을 고려할 수 있습니다. 다음과 같이 기본적으로 프로토콜은 다음과 같습니다

    이 통신은 모두 jmort253 지적한 바와 같이, 일반적으로 URL 변수에 감응 재를 통신보다 더 안전하고, 헤더를 통해 이루어진다.

    다이제스트 액세스 인증은 봄 보안 지원됩니다. 워드 프로세서는 고객의 일반 텍스트 암호에 액세스 할 수 있어야합니다라고하지만 당신은 당신의 클라이언트에 대한 HA1 해시가있는 경우, 당신은 성공적으로 인증 할 수 있습니다, 그것을 알 수 있습니다.

  3. ==============================

    3.정보를 전달하는 토큰과 관련, JSON 웹 토큰 (http://jwt.io) 화려한 기술입니다. 주요 개념은 토큰에 대한 정보 요소 (특허 청구 범위)을 포함하는, 상기 검증 단부 청구 실제로 신뢰할 수 있는지 확인할 수 있도록 그 전체 서명 토큰.

    정보를 전달하는 토큰과 관련, JSON 웹 토큰 (http://jwt.io) 화려한 기술입니다. 주요 개념은 토큰에 대한 정보 요소 (특허 청구 범위)을 포함하는, 상기 검증 단부 청구 실제로 신뢰할 수 있는지 확인할 수 있도록 그 전체 서명 토큰.

    나는이 자바 구현을 사용 : https://bitbucket.org/b_c/jose4j/wiki/Home

    이 봄 모듈 (스프링 보안 JWT)도,하지만 난 그것을 지원하는에보고하지 않았습니다.

  4. ==============================

    4.왜 JSON 웹 토큰과 OAuth를 사용을 시작하지 않는다

    왜 JSON 웹 토큰과 OAuth를 사용을 시작하지 않는다

    http://projects.spring.io/spring-security-oauth/

    OAuth2를은 표준화 된 인증 프로토콜 / 프레임 워크입니다. 공식으로 OAuth2 사양에 따라 :

    당신은 여기에서 더 많은 정보를 찾을 수 있습니다

  5. from https://stackoverflow.com/questions/10826293/restful-authentication-via-spring by cc-by-sa and MIT license