2013-08-01 3 views
8

사용자를 인증하기 위해 내가 잘못하고있는 것이 궁금합니다. 사용자가 계정을 활성화하기 위해 여러 단계를 거친 후 로그인 양식을 무시하고 직접 대시 보드로 가져 가려는 응용 프로그램이 있습니다. 내 인증 공급자로 DaoAuthenticationProvider가 클래스를 사용해야합니다DaoAuthenticationProvider를 사용하여 스프링 보안으로 사용자를 프로그래밍 방식으로 인증하는 방법

protected void automatedLogin(String username, String password, HttpServletRequest request) { 

     try { 
      // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated 
      CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request); 
      UserDetails uDetails = udService.loadUserByUsername(username); 
      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(uDetails, password); 
      token.setDetails(new WebAuthenticationDetails(request)); 
      DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider(); 
      Authentication authentication = authenticator.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      SecurityContextHolder.getContext().setAuthentication(null); 
     } 

    } 

: 여기

처럼 내 자동 로그인 기능이 모습입니다. 나는 올바른 자격 증명 등의 ID, 권한 역할을 포함 UserDetails 객체 모델을 얻고 있다는 것을 확인했다

어딘가에 DaoAuthenticationProvider가 클래스의 길을 따라 널 (null) 포인터에 내가 실행을 인증 메소드를 호출

:

org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider에서 org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser (DaoAuthenticationProvider.java:109) 에서

org.springframework.security.authentication.AuthenticationServiceException

. 인증 (AbstractUserDetail sAuthenticationProvider.java:132) ( ) com.bosch.actions.BaseController.doAutoLogin (BaseController.java:659) . . . '나는 돈으로 내가 널 정말로 확실하지 않다 org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser (DaoAuthenticationProvider.java:101)

에서 java.lang.NullPointerException이 :에 의해 발생 소스 코드를 사용할 수 없습니다.

편집 나는 여기에 소스 코드를 찾을 수 있었다 - https://github.com/SpringSource/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java

내가 명시 적으로 개체의 경우 UserDetailsService를 설정하여 Null 포인터 주위에 얻을 수있었습니다 : 지금

authenticator.setUserDetailsService(udService); 

하지만를 나는 코드에서 이전에 설정된 UserDetails 객체의 디버거에서 보았 기 때문에 제공된 암호가 정확하다는 것을 알고있을 때 잘못된 자격 증명 예외가 발생합니다.

org.springframework.security.authentication.BadCredentialsException : org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks (DaoAuthenticationProvider.java:87) org.springframework.security에서 에서 잘못된 자격 증명. authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate (AbstractUserDetailsAuthenticationProvider.java:149)

+0

봄 보안이 사용 가능한 소스 코드가 수행 오픈 소스입니다. DaoAuthenticationProvider는 스프링 관리 빈 (spring managed bean)으로 설계되었으므로 아마 문제가있을 수 있습니다. – samlewis

답변

9

내가 조립할에 의해 작동하는 스프링 빈 정의 및 자체에 정의 된 모든 속성을 인증을받을 수 있었다 DaoAuthenticationProvider 개체에 프로그래밍 방식으로 설명합니다. 이것을 회상하면 어리석은 질문일지도 모르지만 나는 그것이 누군가를 돕기를 바란다!

수정 코드 :

protected void automatedLogin(String username, String password, HttpServletRequest request) { 

     try { 
      // Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated 
      CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request); 
      CustomMd5PasswordEncoder passEncoder = new CustomMd5PasswordEncoder(); 
      ReflectionSaltSource saltSource = new ReflectionSaltSource(); 
      saltSource.setUserPropertyToUse("salt"); 
      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
      token.setDetails(new WebAuthenticationDetails(request)); 
      DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider(); 
      authenticator.setUserDetailsService(udService); 
      authenticator.setPasswordEncoder(passEncoder); 
      authenticator.setSaltSource(saltSource); 
      Authentication authentication = authenticator.authenticate(token); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      SecurityContextHolder.getContext().setAuthentication(null); 
     } 

    } 
+3

수정 사항을 발견해 주셔서 감사합니다. 솔직히 말해서, 스프링 보안이 사용되는 방법이 아닙니다. 자신 만의 일을 많이하고 있기 때문에 그렇게해서는 안됩니다. – Akshay

+0

이것은 앱에서 스프링 보안을 정상적으로 사용하지 않습니다. 이것은 양식으로 자격 증명을 제공하지 않고 사용자를 로그인해야하는 일회성 인스턴스입니다. 매번 양식을 통해 로그인 할 것이고 스프링 보안 빈은 작업을 수행 할 것입니다. 당신이 대답을 downvoted 사람이라면, StackOverflow에 대한 나의 평판이 불공평하게 상처받는다고 생각하기 때문에 당신이 마음을 바꾸기를 바랍니다. – rawkfist0215

+0

내 친구를 안심하고 투표를하지 않았습니다. 나는 그 대답이 틀렸다고 생각하지 않는다, 나는 봄 보안이 이런 식으로 사용될 의도가 없다고 제안했다. 그리고 태평양 표준시. 아래쪽으로 투표하면 너무 평판이 나빠질 것입니다. :) – Akshay

관련 문제