首页 前端知识 若依ry-vue单点登录实现(通俗易懂)

若依ry-vue单点登录实现(通俗易懂)

2024-01-27 01:01:49 前端知识 前端哥 23 37 我要收藏

具体实现步骤 (可按照以下步骤傻瓜式操作一遍成功后自行调整)

  1. 前端url携带ssoCode
    • ssoCode通过DES加密生成(加密方式自行选择
      • DES(用户名+时间戳)
  2. 在 src/permission.js 文件中加上以下代码
    在这里插入图片描述
  3. 在 store/modules/user.js 文件中的 actions 加上以下代码
    在这里插入图片描述
  4. 在 api/login.js 文件中 加上以下代码
    在这里插入图片描述
  5. 在后端中新增类 SsoLoginController 并加上以下代码
/**
 * 单点登录
 *
 * @author junle
 */
@RestController
@RequestMapping("/sso")
public class SsoLoginController {
    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysLoginService loginService;

    @PostMapping("/login")
    @ApiOperation(value = "单点登录")
    public AjaxResult toThirdPartGetAuthJHaveToken(@RequestBody JSONObject loginInfo) {
        // TODO 1.解密 loginInfo
        // TODO 2.通过解密后的 loginInfo 校验时间戳(是否过期)
        // TODO 3.通过解密后的 loginInfo 校验用户名
        // TODO 4.强制登录
		// String userName = loginInfo.getStr("userName");
        String userName = "admin";
        SysUser sysUser = userService.selectUserByUserName(userName);
        if (sysUser == null) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGIN_FAIL, "用户不存在!"));
            return AjaxResult.error("用户不存在!");
        }
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(sysUser.getUserName(), "ssoLogin");
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
}
  1. 在类SysLoginService中加上login重载方法 代码如下
    /**
     * 登录验证(抄 login 方法 去掉 验证码校验和登录前置校验,其他不变)
     *
     * @param username 用户名
     * @param password 密码
     * @return 结果
     */
    public String login(String username, String password)
    {
        // 验证码校验
        // validateCaptcha(username, code, uuid);
        // 登录前置校验
        // loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        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());
            }
        }
        finally
        {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }
  1. 通过分析 UserDetailsServiceImpl 的 loadUserByUsername 方法得知 需要改造 SysPasswordService 的 validate方法
    在这里插入图片描述
  2. 新增 SpringSecurity 身份认证提供者类 SsoAuthenticationProvider 并加上以下代码
/**
 * 自定义Spring-Security身份验证提供者(扩展单点登录)
 *
 * @author junle
 */
@Component
public class SsoAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userName = authentication.getName();
        String password = authentication.getCredentials().toString();

        // 密码是 ssoLogin 则强制登录
        if ("ssoLogin".equals(password)) {
            UserDetails user = userDetailsService.loadUserByUsername(userName);
            return new SsoAuthenticationToken(user, password, user.getAuthorities());
        }

        // 使用用户详情服务进行正常的身份认证
        UserDetails user = userDetailsService.loadUserByUsername(userName);
        if (user != null && user.getPassword().equals(password)) {
            return new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities());
        }

        // 返回 null 表示认证失败
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
  1. 新增 SpringSecurity 身份验证令牌类SsoAuthenticationToken 并加上以下代码
/**
 * 自定义Spring-Security身份验证令牌
 *
 * @author junle
 */
public class SsoAuthenticationToken extends UsernamePasswordAuthenticationToken {
    public SsoAuthenticationToken(Object principal, Object credentials) {
        super(principal, credentials);
    }

    public SsoAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
        super(principal, credentials, authorities);
    }
}
  1. 在 SecurityConfig 中按下图中配置
    在这里插入图片描述
    在这里插入图片描述
转载请注明出处或者链接地址:https://www.qianduange.cn//article/562.html
评论
发布的文章

06-jquery函数

2024-02-06 15:02:47

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!