根据用户名称实现单点登录

一、参数格式

二、后端实现

复制代码
Controller层
java 复制代码
public class IAccessTokenLoginController extends BaseController {


    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISingleTokenServiceImpl tokenService;

    /**
     * 登录方法
     *
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult singleLogin(@RequestBody LoginBody loginBody) {

        String accessToken = loginBody.getAccessToken();
        if (StringUtils.isNotEmpty(accessToken)) {
            String tokenNew = tokenService.singleLogin(accessToken);
            AjaxResult ajax = AjaxResult.success();
            ajax.put(Constants.TOKEN, tokenNew);
            return ajax;

        } else {
            return AjaxResult.error();
        }


    }
}
复制代码
注意:LoginBody新增变量accessToken
java 复制代码
@Service
public class ISingleTokenServiceImpl implements ISingleTokenService {
    @Autowired
    private TokenService tokenService;
    @Autowired
    private AuthenticationManager authenticationManager;


    public String singleLogin(String accessToken) {
        // 用户验证
        Authentication authentication = null;
        String username =accessToken;
        try
        {
//            username=parseAccessToken(accessToken);
//不用进行处置 直接传参
            authentication = authenticationManager
                    .authenticate(new IAuthenticationToken(username));
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();

        // 生成token
        return tokenService.createToken(loginUser);
    }

    public String parseAccessToken(String accessToken) {
        try {
            // 从 access token 中提取 payload
            Claims claims = Jwts.parser()
                    .parseClaimsJws(accessToken)
                    .getBody();

            // 获取 username
            String username = (String) claims.get("username");

            return username;
        } catch (Exception e) {
            System.out.println("无法解析 access token!" + e);
            return null;
        }
    }
  • 添加自定义IAuthenticationToken
java 复制代码
public class IAuthenticationToken extends AbstractAuthenticationToken {

    private final Object principal;

    public IAuthenticationToken(Object principal) {
        super(null);
        this.principal = principal;
        this.setAuthenticated(false);
    }

    public IAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        super.setAuthenticated(true);
    }

    @Override
    public Object getCredentials() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return this.principal;
    }

    @Override
    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
        if (isAuthenticated) {
            throw new IllegalArgumentException(
                    "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
        }

        super.setAuthenticated(false);
    }

    @Override
    public void eraseCredentials() {
        super.eraseCredentials();
    }

}

添加IAuthenticationProvider
*

java 复制代码
@Component
public class IAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        IAuthenticationToken authenticationToken = (IAuthenticationToken) authentication;

        String username = (String) authenticationToken.getPrincipal();
        UserDetails user = userDetailsService.loadUserByUsername(username);
        IAuthenticationToken result = new IAuthenticationToken(user, Collections.emptyList());
        /*
        Details 中包含了 ip地址、 sessionId 等等属性 也可以存储一些自己想要放进去的内容
        */
        result.setDetails(authenticationToken.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return IAuthenticationToken.class.isAssignableFrom(aClass);
    }
}

修改SecurityConfig 放行我们的请求登录路径 并把自定义认证加进来

.antMatchers("/hello","/single/login","/login", "/register", "/captchaImage").anonymous()

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception

{

复制代码
auth.authenticationProvider(new CustomLoginAuthenticationProvider(userDetailsService));
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
auth.authenticationProvider(iAuthenticationProvider);

}

  • 前端根据后台返回的token进行访问
相关推荐
喜欢猪猪11 分钟前
注解的原理?如何自定义注解?
java·数据库·python
u01040583620 分钟前
Java中的自然语言处理应用
java·开发语言·自然语言处理
明戈戈33 分钟前
设计模式-观察者模式
java·观察者模式·设计模式
苟且.1 小时前
ThreadLocal、InheritableThreadLocal 和 TransmittableThreadLocal
java·多线程
诺浅1 小时前
记一次阿里云服务器java应用无法响应且无法远程连接的问题排查
java·运维·服务器
战神刘玉栋1 小时前
《企业实战分享 · 对象存储服务OSS、S3、MinIO》
java·minio·oss·s3
米糕.1 小时前
【Linux】生物信息学常用命令
java·linux·服务器
虫小宝1 小时前
Java网络编程基础与Socket实现技术
java·开发语言·网络
markix2 小时前
springboot 配置加密,jasypt加解密命令
java·spring boot·后端·jasypt
泡芙萝莉酱2 小时前
Java学习 -Golang开发环境+目录结构+编译+部署
java·学习·golang