1

我尝试实现一项服务,以允许移动应用程序连接并从我的服务器检索信息。

我在我的 CustomUserDetail 中包含了 Spring Security,但没有登录表单,我在 Json 中收到了数据,并手动记录了用户

    Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);

现在我需要使用 MongoDB 实现记住我的服务,但我无法获取存储在我的数据库中的令牌。登录用户时如何模拟“记住我”检查?这是强制性的,因为如果不这样做,每次我重新启动服务器时所有用户都会注销

这是我的安全配置文件:

<http use-expressions="true">
    <remember-me services-ref="rememberMeServices" key="myPersistentKey" />
    <logout invalidate-session="true" logout-url="/logout" />
    <intercept-url pattern="/users/**" access="isAuthenticated()" />
    <intercept-url pattern="/**" access="permitAll" />
    <form-login authentication-failure-url="/denied" login-page="/denied" />
    <access-denied-handler error-page="/denied" />
</http>

<beans:bean id="customUserDetailsService" class="com.service.test.security.CustomUserDetailsService" />

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

<beans:bean id="mongoDBTokenRepository" class="com.service.test.security.MongoPersistentTokenRepositoryImpl" />

<beans:bean id="rememberMeServices"
    class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
    <beans:constructor-arg value="myPersistentKey" />
    <beans:constructor-arg ref="customUserDetailsService" />
    <beans:constructor-arg ref="mongoDBTokenRepository" />
    <beans:property name="alwaysRemember" value="true" />
</beans:bean>

MongoPersistentTokenRepositoryImpl 是我对 PersistentTokenRepository 的实现

@Autowired
private RememberMeTokenRepository rememberMeTokenRepository;

@Override
public void createNewToken(PersistentRememberMeToken token) {
    RememberMeToken newToken = new RememberMeToken(token);
    this.rememberMeTokenRepository.save(newToken);
}

@Override
public void updateToken(String series, String tokenValue, Date lastUsed) {
    RememberMeToken token = this.rememberMeTokenRepository.findBySeries(series);
    if (token != null) {
        token.setTokenValue(tokenValue);
        token.setDate(lastUsed);
        this.rememberMeTokenRepository.save(token);
    }

}

@Override
public PersistentRememberMeToken getTokenForSeries(String seriesId) {
    RememberMeToken token = this.rememberMeTokenRepository.findBySeries(seriesId);
    return new PersistentRememberMeToken(token.getUsername(), token.getSeries(), token.getTokenValue(), token.getDate());
}

@Override
public void removeUserTokens(String username) {
    List<RememberMeToken> tokens = this.rememberMeTokenRepository.findByUsername(username);
    this.rememberMeTokenRepository.delete(tokens);
}

这是我实现 UserDetailsS​​ervice 的 CustomUserDetailsS​​ervice

@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 email) throws UsernameNotFoundException {
    try {
        User21 domainUser = userRepository.findByEmail(email);

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

        return new CustomUser(domainUser.getId(), domainUser.getEmail(), domainUser.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
        // getAuthorities(domainUser.getRole().getRole()));
                getAuthorities(2));

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

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

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

        return new CustomUser(user.getId(), user.getEmail(), user.getPassword().toLowerCase(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
        // getAuthorities(domainUser.getRole().getRole()));
                getAuthorities(2));

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

public void logUserIn(User21 user) throws Exception{
    UserDetails userDetails = loadUser(user);
    Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

我的开发基于这篇很棒的文章

http://www.jiwhiz.com/post/2013/2/Add_RememberMe_Authentication_With_Spring_Security

但一定有什么我想念的。

谢谢!

4

0 回答 0