2013-03-11 4 views
0

Я пытаюсь реализовать авторизацию весны безопасности с использованием настраиваемого фильтра.Весенняя безопасность; custom-filter и user-service-ref не работают вместе

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); 
    } 
} 

MyAuthenticationSuccessHandler

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

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()); 
    } 
} 

Когда я пытаюсь войти, он приходит к CustomUserDetailsService и успешно извлекать пользовательские данные из базы данных.

Но он всегда получает доступ к аутентификацииFailureHandler, верны ли учетные данные или нет. (INFO : com.my.org.MyAuthenticationFailureHandler - point-3)

Может ли кто-нибудь помочь мне в этом? Благодаря

ответ

3

Вы настроили провайдер аутентификации использовать sha пароль кодировку (<password-encoder hash="sha"/>), что означает, что она будет Ша-закодировать пароль, представленный в запросе входящего входа, и сравните это закодированное значение с паролем, сохраненным в UserDetails объекте (который, как ожидается, также будет закодирован). Когда вы создаете объект UserDetails в CustomUserDetailsService.loadUserByUsername(), пользователь загружается из репозитория, и вы преобразовываете его пароль с toLowerCase(). Теперь, почему бы вам это сделать? Это значение должно быть закодированным паролем. Преобразуя хэш пароля, вы гарантируете, что пользователь не сможет войти в систему с его первоначальным паролем. Но даже если вы храните пароль в виде обычного текста (в этом случае необходимо удалить конфигурацию password-encoder), почему вы сделали бы его строчным в UserDetails? Если вы это сделаете, и пользователь установит свой пароль на «Секрет», позже он сможет только аутентифицироваться с «тайной».

+0

спасибо. Я не заметил ваших очков из-за спешки. Моя проблема исправлена. – Unknown