springsecurity实现两套登录系统
1.难点
springsecurity一般授权认证只有一套的授权认证流程,但是我的业务上需要有一个后台登录,一个手机端登录,登录时候校验密码的方式不一样,那么实现两个认证流程是一个问题
2.解决
1.通过实现两个认证授权类去实现
第一个用户端:
package cn.leadingtv.oauth.config;
import cn.leadingtv.oauth.entity.LoginUser;
import lombok.extern.slf4j.Slf4j;
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.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.Collection;
/**
* @author xjq
* @version 1.O.0
* @date 2023/3/14 10:43
*/
@Component
@Slf4j
public class UserAuthenticationProvider implements AuthenticationProvider {
/**
* 自定义MD5 加密
*/
@Autowired
private UserPasswordEncoder userPasswordEncoder;
@Autowired
private UserDetailsService userService;
/**
* 自定义验证方式
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//获取用户输入的用户名和密码
String username = authentication.getName();
String password = (String) authentication.getCredentials();
//通过获取的用户名,得到userDetails对象
LoginUser user = (LoginUser)userService.loadUserByUsername(username);
//加密过程在这里体现,明文,密文
if (!userPasswordEncoder.matches(password, user.getPassword())) {
throw new UsernameNotFoundException("账号密码错误");
}
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
第二个管理员端:
package cn.leadingtv.oauth.config;
import cn.leadingtv.oauth.entity.LoginUser;
import lombok.extern.slf4j.Slf4j;
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.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.Collection;
/**
* @author xjq
* @version 1.O.0
* @date 2023/3/14 10:43
*/
@Component
@Slf4j
public class AdminAuthenticationProvider implements AuthenticationProvider {
/**
* 自定义MD5 加密
*/
@Autowired
private MD5PasswordEncoder myPasswordEncoder;
@Autowired
private UserDetailsService userService;
/**
* 自定义验证方式
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//获取用户输入的用户名和密码
String username = authentication.getName();
String password = (String) authentication.getCredentials();
//通过获取的用户名,得到userDetails对象
LoginUser user = (LoginUser)userService.loadUserByUsername(username);
//加密过程在这里体现,明文,密文
if (!myPasswordEncoder.matches(password, user.getPassword())) {
throw new UsernameNotFoundException("管理员账号密码错误");
}
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
用户加密类(无需验证密码):
package cn.leadingtv.oauth.config;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class UserPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
//对rawPassword进行加密,具体如何加密根据业务来,encode是加密后的字符串
return encode;
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return true;
}
}
管理员密码加密类:
package cn.leadingtv.oauth.config;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class MD5PasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
//对rawPassword进行加密,具体如何加密根据业务来,encode是加密后的字符串
return encode;
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
log.info("原密码===>{}", rawPassword);
log.info("加密后的密码===>{}", encodedPassword);
//给rawPassword进行加密得到encode,加密规则根据需求来
return ObjectUtil.equals(encodedPassword, encode);
}
}
在登录接口实现类分别注入两个授权认证类:
@Service
@Slf4j
public class OauthLoginServiceImpl implements IOauthLoginService {
@Autowired
private UserAuthenticationProvider userAuthenticationProvider;
@Autowired
private AdminAuthenticationProvider adminAuthenticationProvider;
}
然后在自己的登录接口上如果是用户登录接口就选用userAuthenticationProvider.authenticate,如果是管理员接口就选用adminAuthenticationProvider.authenticate即可
3.总结
需要实现两个认证授权类以及两个密码加密验证类,然后根据自己的功能选择相应的授权认证类
本文介绍了如何在SpringSecurity中设计并实现两个独立的认证流程,分别针对用户端和管理员端,通过自定义AuthenticationProvider和PasswordEncoder来处理不同的密码加密策略。
1009

被折叠的 条评论
为什么被折叠?



