2013-03-11 3 views
0

사용자 정의 필터를 사용하여 봄 보안 인증을 구현하려고합니다.스프링 보안; 사용자 정의 필터 및 사용자 서비스 참조가 함께 작동하지 않음

security.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security-3.1.xsd 
     http://www.springframework.org/schema/util 
     http://www.springframework.org/schema/util/spring-util-3.1.xsd"> 

    <http pattern="/resources" security="none" /> 

    <http auto-config="false" use-expressions="true" entry-point- ref="authenticationEntryPoint"> 
     <custom-filter position="BASIC_AUTH_FILTER" ref="loginFilter"/> 
     <intercept-url pattern="/login" access="permitAll" /> 
     <intercept-url pattern="/favicon.ico" access="permitAll"/> 
    </http> 

    <beans:bean id="authenticationEntryPoint" class="com.my.org.MyAuthenticationEntryPoint"/> 


    <beans:bean id="loginFilter" 
     class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
     <beans:property name="authenticationManager" ref="authenticationManager"/> 
     <beans:property name="filterProcessesUrl" value="/j_spring_security_check"/> 
     <beans:property name="authenticationSuccessHandler" > 
      <beans:bean class="com.my.org.MyAuthenticationSuccessHandler"/> 
    </beans:property> 
     <beans:property name="authenticationFailureHandler"> 
      <beans:bean class="com.my.org.MyAuthenticationFailureHandler"/> 
     </beans:property> 
    </beans:bean> 

    <authentication-manager alias="authenticationManager"> 
      <authentication-provider user-service-ref="customUserDetailsService"> 
        <password-encoder hash="sha"/> 
      </authentication-provider> 
    </authentication-manager> 

</beans:beans> 

CustomUserDetailsService

/** 
* A custom {@link UserDetailsService} where user information 
* is retrieved from a JPA repository 
*/ 
@Service 
@Transactional(readOnly = true) 
public class CustomUserDetailsService implements UserDetailsService { 

private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class); 

@Autowired 
private UserRepository userRepository; 

/** 
* Returns a populated {@link UserDetails} object. 
* The username is first retrieved from the database and then mapped to 
* a {@link UserDetails} object. 
*/ 
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
    try { 

     logger.info("username-1-->"+username); 
     com.cbr.model.User domainUser = userRepository.findByUsername(username); 
     logger.info("domainUser-1-->"+domainUser.getPassword()); 
     logger.info("role-1-->"+domainUser.getRole().getRole()); 

     boolean enabled = true; 
     boolean accountNonExpired = true; 
     boolean credentialsNonExpired = true; 
     boolean accountNonLocked = true; 

     return new User(
       domainUser.getUsername(), 
       domainUser.getPassword().toLowerCase(), 
       enabled, 
       accountNonExpired, 
       credentialsNonExpired, 
       accountNonLocked, 
       getAuthorities(domainUser.getRole().getRole())); 

    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

/** 
* Retrieves a collection of {@link GrantedAuthority} based on a numerical role 
* @param role the numerical role 
* @return a collection of {@link GrantedAuthority 
*/ 
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) { 
    List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role)); 
    return authList; 
} 

/** 
* Converts a numerical role to an equivalent list of roles 
* @param role the numerical role 
* @return list of roles as as a list of {@link String} 
*/ 
public List<String> getRoles(Integer role) { 
    List<String> roles = new ArrayList<String>(); 

    if (role.intValue() == 1) { 
     roles.add("ROLE_USER"); 
     roles.add("ROLE_ADMIN"); 

    } else if (role.intValue() == 2) { 
     roles.add("ROLE_USER"); 
    } 

    return roles; 
} 

/** 
* Wraps {@link String} roles to {@link SimpleGrantedAuthority} objects 
* @param roles {@link String} of roles 
* @return list of granted authorities 
*/ 
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) { 
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
    for (String role : roles) { 
     authorities.add(new SimpleGrantedAuthority(role)); 
    } 
    return authorities; 
} 

}

MyAuthenticationEntryPoint

,
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint { 

    private Log log = LogFactory.getLog(MyAuthenticationEntryPoint.class); 

    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 

     log.info("point-1"); 

     response.sendError(HttpServletResponse.SC_FORBIDDEN); 
    } 
} 

public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { 

    private Log log = LogFactory.getLog(MyAuthenticationFailureHandler.class); 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,AuthenticationException exception) throws IOException, ServletException { 
     log.info("point-3"); 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage()); 
    } 
} 

내가 로그인을 시도

public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 

    private Log log = LogFactory.getLog(MyAuthenticationSuccessHandler.class); 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,Authentication authentication) throws IOException, ServletException { 
     // This is actually not an error, but an OK message. It is sent to avoid redirects. 
     log.info("point-2"); 
     response.sendError(HttpServletResponse.SC_OK); 
    } 
} 

MyAuthenticationFailureHandler MyAuthenticationSuccessHandler, 그것은 CustomUserDetailsService에 와서 성공적으로 데이터베이스에서 사용자 정보를 검색 할 수 있습니다.

그러나 자격 증명이 올바른지 여부는 항상 authenticationFailureHandler에 액세스합니다. (INFO : com.my.org.MyAuthenticationFailureHandler - point-3)

아무도 도와 줄 수 있습니까? 감사

답변

3

귀하는 들어오는 로그인 요청에 제시된 암호 인코딩을-SHA와합니다 (UserDetails 객체에 저장된 암호와 그 인코딩 된 값을 비교하는 것을 의미 sha 암호 부호화 (<password-encoder hash="sha"/>)을 사용하는 인증 공급자 구성된 결과적으로 sha 인코딩도 될 것으로 예상 됨). 개체를 CustomUserDetailsService.loadUserByUsername()에 만들면 사용자가 저장소에서로드되고 toLowerCase()으로 암호를 변환합니다. 자, 왜 지구상에서 그렇게 할 수 있니? 이 값은 sha 인코딩 된 암호로되어 있습니다. 암호 해시를 변환하면 사용자가 원래 암호로 로그인 할 수 없다는 것을 보증하게됩니다. 암호를 일반 텍스트 (이 경우 password-encoder 구성을 제거해야 함)에 저장하더라도 UserDetails에 소문자로 표시되는 이유는 무엇입니까? 사용자가 암호를 "Secret"으로 설정하면 나중에 "secret"로만 인증 할 수 있습니다.

+0

고맙습니다. 나는 서두 르기 때문에 당신의 점수를 알아 채지 못했습니다. 내 문제가 해결되었습니다. – Unknown