Spring 问题请记住我
在我的 Spring 安全应用程序中,我有自定义身份验证提供程序,可以对自定义身份验证对象进行身份验证并返回自定义身份验证对象,并且身份验证工作正常,但我对 Spring Remember me 服务有问题,它无法正常工作
但是当我通过正常的 Spring Security 进行身份验证时,通过使用 UserDetailService 然后“记住我”效果很好,我的代码如下
package com.websopti.wotms.auth;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import com.websopti.wotms.entity.User;
import com.websopti.wotms.enums.ErrorKey;
import com.websopti.wotms.service.UserService;
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
public UserService userService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String email = authentication.getPrincipal().toString();
String password = authentication.getCredentials().toString();
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
String username = null;
try {
username = userService.authenticate(email, password);
} catch (IOException e) {
e.printStackTrace();
}
if(username != null && !username.equals("0")){
User user = userService.findByEmail(email);
if (user != null) {
authorities.add(new SimpleGrantedAuthority(user.getRole().name()));
return (new UsernamePasswordAuthenticationToken(user, null, authorities));
} else {
User newUser = new User();
newUser.setName(username);
newUser.setEmail(email);
newUser.setPassword(password);
userService.register(newUser);
newUser = userService.findById(newUser.getId());
authorities.add(new SimpleGrantedAuthority(newUser.getRole().name()));
return (new UsernamePasswordAuthenticationToken(newUser, null, authorities));
}
} else {
throw new UsernameNotFoundException(ErrorKey.USER_NOT_FOUND.name());
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
如果我使用以下代码进行身份验证,那么它可以正常工作
package com.websopti.wotms.auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.websopti.wotms.entity.User;
import com.websopti.wotms.enums.ErrorKey;
import com.websopti.wotms.service.UserService;
@Service
public class AuthenticationService implements UserDetailsService {
@Autowired
public UserService userService;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userService.findByEmail(email);
if(user != null)
return user;
else
throw new UsernameNotFoundException(ErrorKey.USER_NOT_FOUND.name());
}
}
有人可以指导我代码中存在什么问题吗?
最佳答案
根据doc
Note that both implemementations require a UserDetailsService. If you are using an authentication provider which doesn't use a UserDetailsService (for example, the LDAP provider) then it won't work unless you also have a UserDetailsService bean in your application context.
默认的 Remember-me 使用示例 TokenBasedRememberMeServices processAutoLoginCookie() 方法从 cookie 中检索 userDetails 以验证用户/密码详细信息。所以你需要一个自定义的 userDetailsService 检查 this或this
更新:
基本上记住我功能有两件事
- 成功登录后,它会创建一个“remeber-me”浏览器cookie,其中包含基于用户名、密码的 token (如果需要,可以计算 token 并将其保存在数据库中,也可以动态计算用户、密码的哈希值) .
- 当用户尝试在没有任何 session 的情况下访问安全页面( session 因超时而过期)时,RememberMe 服务将尝试通过从 cookie 中检索用户详细信息来自动登录用户,并在需要时验证用户详细信息。
如果您没有返回 UserDetails 信息的 UserDetailsService,那么您需要像 TokenBasedRememberMeServices 一样实现 RememberMeServices 并调整代码。
关于java - Spring security Remember me 和自定义身份验证提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32311925/