2015-01-07 3 views
0

Android 클라이언트 용 스프링 서버를 만들고 기본 인증을 사용하려고합니다. 클라이언트가 인증 한스프링 기반 서버에서 http 기본 인증 세션을 수행하는 방법

@RequestMapping(value = "login", method = RequestMethod.GET, produces = "application/json") 
public @ResponseBody Message login(HttpSession session) { 
    logger.info("Accessing protected resource sid:"+session.getId()); 
    return new Message(100, "Congratulations!", "You have logged in."); 
} 

@RequestMapping(value = "play", method = RequestMethod.GET, produces = "application/json") 
public @ResponseBody Message play(HttpSession session) { 
    logger.info("Accessing protected play resource"); 
    return new Message(100, "Congratulations!", "Launching play."); 
} 

되면, 로그인 할 때, 나는 그것이 연극을 호출하는 동안 재 인증이 필요하지 않으려는 다음과 같이 내가 컨트롤러를 가지고있다.

protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http 
       .csrf().disable() 
       .authorizeRequests() 
       .antMatchers("/signup","/about").permitAll() 
       .anyRequest().authenticated() 
       .and() 
       .httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); 

     // @formatter:on 
    } 

} 

나는 위의 세션을 사용하려고 노력하지만 로그인 및 플레이의 요청 처리기에서 세션 ID를 인쇄하려고하면, 나는 인증으로 로그인 한 후 다른 ID를 얻을 :

내 보안 설정입니다 . HttpBasic 보안을 사용하고 있습니다. HttpBasic 보안에서 세션을 가질 수 있습니까? 나는 그것이 무국적이며 하나가 될 수 없다는 것을 나타내는듯한 기사를 읽었다. 해결 방법이 있습니까 아니면 다른 보안 모델로 전환해야합니까?

클라이언트 코드 : 로그인에 다음과 같이 클라이언트 측에서

, 내가 요청을 보냅니다.

@Override 
    protected Message doInBackground(Void... params) { 
     //final String url = getString(R.string.base_uri) + "/getmessage"; 
     final String url = "http://10.0.2.2:8080/login"; 

     // Populate the HTTP Basic Authentitcation header with the username and password 
     HttpAuthentication authHeader = new HttpBasicAuthentication(username, password); 
     HttpHeaders requestHeaders = new HttpHeaders(); 
     requestHeaders.setAuthorization(authHeader); 
     requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 

     // Create a new RestTemplate instance 
     RestTemplate restTemplate = new RestTemplate(); 
     restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter()); 

     try {    // Make the network request 
      Log.d(TAG, url); 
      ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(requestHeaders), Message.class); 

      if(response.getBody().getId() == 100) 
       login_success = true; 
      return response.getBody(); 

나는 유사하게 '놀이'에 대한하지만, 인증 헤더를 통과 할 필요없이 클라이언트 코드를 작성하는 것을 시도하고있다. 나는 어떻게 든 세션 요청 매개 변수를 요청 헤더에 전달하여 서버에 같은 세션의 일부임을 나타내지 만 그 작업을 수행하는 방법을 파악할 수 없다고 생각합니다.

+0

HTTP 기본 인증은 일반적으로 상태 비 저장이지만 반드시 그렇게 할 필요는 없습니다. 고객이 고장 났다고 확인 했습니까? – holmis83

+0

감사합니다. 내 클라이언트에서 내 요청에 현재 세션 관련 매개 변수를 보내지 않습니다. 나는 그 줄에서 생각할 것이다 ... – doomguy

+0

@ holmis83 나는 나의 클라이언트 코드를 업데이트했다. 내 머리글에 세션 매개 변수를 전달해야한다고 생각합니다. 이게 맞는 것인가? 그렇다면 여기에 어떻게 세션 ID를 얻습니까? 이 게시물을 발견 : http://springinpractice.com/2012/04/08/sending-cookies-with-resttemplate하지만 클라이언트에서 세션 ID를 얻는 방법에 관해서는 명확하지 않습니다. 올바른 방향으로 .. – doomguy

답변

1

세션과 상태 기반 통신을 보관하려고하지만 RestTemplate이 상태없는 방식으로 작동하므로 세션이 작동하지 않습니다. 상태 (즉 세션 ID)를 로그인에서 다음 호출로 유지하지 않습니다. 맞춤 설정만으로 ClientHttpRequestFactory이 작품을 볼 수있었습니다 (Android에서는 확실하지 않습니다).

상태와 통신하려는 경우 Apache HttpClient를 볼 수 있습니다. 요청간에 다시 사용하는 HttpContext과 함께 사용하면 상태가 유지됩니다.

세션 ID를 직접 조작 할 가능성이 있지만 권장 할 수는 없습니다.

+0

고마워, 나는 HttpClient 접근 방식을 시도 할 것이다. – doomguy

+0

감사합니다. 재사용 된 httpcontext와 함께 접근 방식을 시도하고 그것은 작동합니다. 세션 ID 추적이 권장되지 않는 이유에 대해 간단히 설명해 주시겠습니까? 세션 고정 공격과 관련이 있습니까? – doomguy

+0

@doomguy 휠의 재발생은 오류가 발생하기 쉽기 때문에 라이브러리를 사용할 때 그 수준에서 작업해서는 안된다는 의미였습니다. – holmis83