在我的春季安全应用程序中,我有自定义身份验证提供程序验证并返回自定义身份验证对象,身份验证工作正常但我遇到问题春天记住我的服务它无法正常工作
但是当我通过正常的Spring安全性进行身份验证时,通过使用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());
}
}
有人能指导我在我的代码中出现什么问题吗?
答案 0 :(得分:0)
根据doc
请注意,这两个实现都需要UserDetailsService。如果你 正在使用不使用a的身份验证提供程序 UserDetailsService(例如,LDAP提供程序)然后它不会工作 除非您的应用程序中还有一个UserDetailsService bean 上下文。
示例默认值remember-me使用TokenBasedRememberMeServices processAutoLoginCookie()方法从cookie中检索userDetails以验证用户/密码详细信息。因此,您需要自定义userDetailsService检查this或this
更新:
基本上记得我的功能有两件事
如果您没有返回UserDetails信息的UserDetailsService,那么您需要实现RememberMeServices,如TokenBasedRememberMeServices并调整代码。
答案 1 :(得分:0)
我遇到同样的问题,并添加auth.userDetailsService(userService);
修复
@Autowired
private AuthenticationService userDetailsService;
@Autowired
private CustomAuthenticationProvider provider;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//将验证过程交给自定义验证工具
auth.userDetailsService(userService);
auth.authenticationProvider(provider);
}
答案 2 :(得分:0)
当您使用Spring自定义身份验证提供程序时,您需要自己记住我的服务并将其配置为spring security配置文件。
以下是供参考的链接: https://samerabdelkafi.wordpress.com/2016/01/25/secure-angularjs-application-with-spring-security/
记住我和自定义身份验证提供程序的问题是:public UserDetails loadUserByUsername(String mobile)throws UsernameNotFoundException { 的System.out.println(移动); //你在这里 如果您已经过身份验证,则获取经过身份验证的主体用户对象 不会得到任何用户deatils。 }
我不确定以下解决方案是否对,但对我来说效果很好。
public Authentication authenticate(Authentication auth) throws AuthenticationException { Customer user = null; user = customerDataManager.findCustomerByMobile(auth.getName()); if ((user == null)) { throw new BadCredentialsException("Invalid username or password"); } final Authentication result = super.authenticate(auth); return result; }
而不是返回UsernamePasswordAuthenticationToken对象返回身份验证对象。