2012-01-06 3 views
4

이것은 스프링 보안 질문입니다.스프링 3, 스프링 보안. 인증 된 사용자 객체 추출

내 응용 프로그램에는 User 개체가 도메인 개체로 있습니다. 이 객체는 Spring UserDetails 객체를 지원하기위한 구현을 포함합니다. 인증 (로그인/로그 아웃) 프로세스가 정상적으로 작동합니다.

어려운 점은 코드에서 '비즈니스 논리'결정을 내리기 위해 세션에서 해당 개체를 추출해야한다는 것입니다.

나는 SecurityContextHolder를 쿼리하는 것에 대해 읽었지만, 솔직히 말해서, 여러 스프링 버전이 이러한 토론의 요소 인 것처럼 보인다면 나는 최선의 접근 방식이 무엇인지 모릅니다. 또한 Principal 객체는 액세스 수준이나 역할 정보가 포함되어 있지 않기 때문에 저를위한 솔루션이 아닙니다.

다음은 간단한 문제를 설명하는 컨트롤러입니다. 내 사용자 도메인 객체가 하드 코드되어 있습니다. 그 블록을 Spring Security 세션에서 User 객체를 얻을 수있는 코드로 대체해야합니다. Spring 3 내에서이 작업을 수행하는 가장 좋은 방법을 찾고 있습니다.

  1. 이 객체를 내 도메인 객체로 가져올 수 있습니까? 아니면 Spring UserDetails 객체로 가져 와서 수동으로 변환해야합니까?
  2. 이 보안 컨텍스트 조회가 어떻게 든 내 컨트롤러에 주입 될 수 있습니까?

    public class HomeController { 
        @RequestMapping(value="/home.html", method=RequestMethod.GET) 
        public ModelAndView getHomePage(Map<String, Object> model) { 
    
         // Get current user 
         User currentUser=new User(); 
         currentUser.setUserName("Admin"); 
         currentUser.setAccessLevel(UserAccessLevel.ADMINISTRATOR); 
    
         // Construct HomePage bean 
         HomeBean bean=new HomeBean(); 
         bean.setCurrentUserName(currentUser.getUserName()); 
    
         // Construct list of catalogs 
         Collection<String> catalogList=new ArrayList<String>(); 
         catalogList.add("articles"); 
         catalogList.add("files"); 
         catalogList.add("comments"); 
         if(currentUser.hasAdministratorAccessLevel()) { 
          catalogList.add("users"); 
         } 
         bean.setCatalogList(catalogList); 
    
         // Construct and return ModelAndView 
         ModelAndView mav=new ModelAndView(); 
         mav.setViewName(WebView.HOME_PAGE.getViewName()); 
         mav.addObject(bean.getBeanId(), bean); 
    
         return mav; 
        } 
    

=== 업데이트 2012-01-07 =============================== =========================

나는 루크의 제안으로 일하고있다. 세션에서 UserDetails를 가져 와서 반환 된 내 도메인 User 객체로 변환하는 메소드는 내 UserService에 있습니다.

여기 내 컨트롤러 :

@Controller 
public class HomeController { 
@Autowired 
private UserService userService; 

@RequestMapping(value="/home.html", method=RequestMethod.GET) 
public ModelAndView getHomePage(Map<String, Object> model) { 

    // Construct HomePage bean 
    HomeBean bean=new HomeBean(); 
    User currentUser=userService.getCurrentlyAuthenticatedUser(); 
    bean.setCurrentUserName(currentUser.getUserName()); 

그리고 여기에() UserServiceImpl.getCurrentlyAuthenticatedUser에서 키 코드입니다 :

@Override 
public User getCurrentlyAuthenticatedUser() { 
    User currentUser=new User(); 

    Authentication a = SecurityContextHolder.getContext().getAuthentication(); 
    UserDetails currentUserDetails = (UserDetails) a.getPrincipal(); 
    if(currentUserDetails==null) { 
     return currentUser; 
    } 

    currentUser.setUserName(currentUserDetails.getUsername()); 

이 작동하지만 나는이 권리를하고 있는가? 피드백을 많이 주셨습니다. 세션에서 내 사용자 도메인 개체를 검색 할 수 없습니다. Spring의 UserDetails 객체를 가져오고 내 도메인 User 객체를 생성하지만이 과정에서 일부 정보가 손실됩니다.

답변

8

일반적으로 성공한 Authentication에 포함 된 주요 개체는 사용자 개체의 인스턴스입니다. 그래서, 빠른 솔루션, 또한

Authentication a = SecurityContextHolder.getContext().getAuthentication(); 
User currentUser = (User)a.getPrincipal(); 

하지만를 사용, 어떻게 inject a custom security context accessor에에 (비슷한 질문에) 난 그냥 준 대답에서 볼 수도 있습니다 (당신이 일 것을 일단).

+0

java.lang.ClassCastException : org.springframework.security.core.userdetails.User를 com.modelsite.domain.User로 캐스팅 할 수 없습니다. – jacekn

+0

사용자 도메인 객체로 User 객체를 검색 할 수없는 경우 고통스러워. UserDetails에서 내가 다루는 액세스 수준을 알아낼 수는 있지만 필요한 정보는 userId입니다. userName과 userId는 저에게 두 가지 다른 것들입니다. 세션에서이 항목을 검색 할 수 없다면 데이터베이스에서 사용자를 가져와야 함을 의미합니다. 내가 피하고 싶은 것. – jacekn

+0

사용자가 인증 할 때 사용자 객체의 인스턴스 (커스텀'UserDetails' 인스턴스)를 반환하는'UserDetailsService'로 스프링 보안을 설정해야합니다. 그렇게하면 새로운 중간 객체를 만들지 않고'SecurityContextHolder'에서 직접 사용할 수 있습니다. UserDetailsService 사용에 대한 자세한 내용은 [참조 설명서] (http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#tech-userdetailsservice)를 참조하십시오. –

관련 문제