首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring安全性.自定义过滤器和用户服务.推荐不一起工作

Spring安全性.自定义过滤器和用户服务.推荐不一起工作
EN

Stack Overflow用户
提问于 2013-03-11 21:58:25
回答 1查看 4.8K关注 0票数 0

我正在尝试使用自定义过滤器来实现spring安全授权。

security.xml

代码语言:javascript
复制
<?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

代码语言:javascript
复制
/**
 * 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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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,并成功地从数据库中检索用户详细信息。

但无论凭据是否正确,它总是访问authenticationFailureHandler。(INFO : com.my.org.MyAuthenticationFailureHandler - point-3)

有人能帮我吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-11 22:38:12

您将身份验证提供程序配置为使用sha密码编码(<password-encoder hash="sha"/>),这意味着它将对传入登录请求中显示的密码进行编码,并将该编码值与存储在UserDetails对象中的密码进行比较(因此预期也会对其进行沙编码)。当您在UserDetails中创建CustomUserDetailsService.loadUserByUsername()对象时,用户将从存储库中加载,并使用toLowerCase()转换他的密码。现在,你到底为什么要这么做?这个值应该是一个沙编码的密码。通过转换密码的哈希,您可以保证用户无法使用他的原始密码登录。但是,即使您将密码存储在纯文本中(在这种情况下,应该删除password-encoder配置),为什么要用UserDetails将其小写呢?如果您这样做,并且用户将他的密码设置为“机密”,那么他以后只能使用“机密”进行身份验证。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15349507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档