最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

快播:第三方登录组件-JustAuth

来源:博客园


(相关资料图)

1、新增依赖

   me.zhyd.oauth   JustAuth   1.16.5

2、前端示例

<script>export default {  name: "SocialSignin",  methods: {   // 请求后台获取跳转路径    thirdLoginClick(source) {      this.$store.dispatch("user/thirdLogin", {source: source}).then(() => {      }).catch(() => {      })    }  }}</script>
// 第三方登录  thirdLogin({commit}, userInfo) {    const {source} = userInfo    return new Promise((resolve, reject) => {      thirdLogin({source: source.trim()}).then(response => {        console.log("第三方登录返回", response)        if (response.data.code === "200") {          window.location.href = response.data.url        } else {          Message.warning(response.data.msg);        }        resolve()      }).catch(error => {        reject(error)      })    })  }
export function thirdLogin(data) {  return request({    url: "/login/render",    method: "post",    params: {source: data.source}  })}

3、后端示例

获取跳转路径
import com.mxy.common.core.utils.ServiceResult;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import me.zhyd.oauth.request.AuthRequest;import me.zhyd.oauth.utils.AuthStateUtils;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import java.util.*;/** * 第三方登录认证 */@RestController@RequestMapping("/api/login")@Api(value = "第三方登录相关接口", tags = {"第三方登录相关接口"})@Slf4jpublic class AuthRestApi {    @Resource    private AuthUtil authUtil;    @ApiOperation(value = "系统认证", notes = "系统认证")    @RequestMapping("/render")    public String renderAuth(String source) {        log.info("进入第三方认证:" + source);        Map map = new HashMap<>();        AuthRequest authRequest = authUtil.getAuthRequest(source);        if (authRequest == null) {            map.put("code", "201");            map.put("msg", "系统未开启该登录方式");            return ServiceResult.success(map);        }        String token = AuthStateUtils.createState();        String authorizeUrl = authRequest.authorize(token);        log.info("获取返回url:" + authorizeUrl);        map.put("code", "200");        map.put("url", authorizeUrl);        return ServiceResult.success(map);    }}

拦截登录回调接口(ThirdPartyAuthenticationFilter)

import me.zhyd.oauth.model.AuthCallback;import org.springframework.security.authentication.AuthenticationServiceException;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;import org.springframework.security.web.util.matcher.AntPathRequestMatcher;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 第三方登录-拦截器 * 拼接入参 */public class ThirdPartyAuthenticationFilter extends AbstractAuthenticationProcessingFilter {    public static String EXTEND_LOGIN_URL = "/api/login/callback/**";    private boolean getOnly = true;    /**     * 表示这个 Filter 拦截 /api/login/callback/** 接口     */    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher(EXTEND_LOGIN_URL, "GET");    public ThirdPartyAuthenticationFilter() {        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);    }    @Override    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {        if (this.getOnly && !"GET".equals(request.getMethod())) {            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());        } else {            ThirdPartyAuthenticationToken authRequest = new ThirdPartyAuthenticationToken(getSourceType(request), getCallback(request));            this.setDetails(request, authRequest);            return this.getAuthenticationManager().authenticate(authRequest);        }    }    protected void setDetails(HttpServletRequest request, ThirdPartyAuthenticationToken authRequest) {        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));    }    /**     * 组装请求     */    private AuthCallback getCallback(HttpServletRequest request) {        return AuthCallback.builder()                .code(request.getParameter("code"))                .auth_code(request.getParameter("auth_code"))                .authorization_code(request.getParameter("authorization_code"))                .oauth_token(request.getParameter("oauth_token"))                .state(request.getParameter("state"))                .oauth_verifier(request.getParameter("oauth_verifier"))                .build();    }    /**     * 判断-登录系统类型     */    private String getSourceType(HttpServletRequest request) {        String uri = request.getRequestURI();        int common = EXTEND_LOGIN_URL.length() - 2;        int start = uri.indexOf(EXTEND_LOGIN_URL.substring(0, common));        return uri.substring(start + common);    }}
封装用户信息(ThirdPartyAuthenticationToken)
import me.zhyd.oauth.model.AuthCallback;import org.springframework.security.authentication.AbstractAuthenticationToken;import org.springframework.security.core.GrantedAuthority;import java.util.Collection;/** * 模仿 UsernamePasswordAuthenticationToken * 封装用户信息 */public class ThirdPartyAuthenticationToken extends AbstractAuthenticationToken {    /**     * 认证返回     */    private AuthCallback callback;    /**     * 登录类型     */    private String source;    /**     * 用户实体     */    private Object principal;    /**     * 用户id     */    private Object credentials;    public ThirdPartyAuthenticationToken(String source, AuthCallback callback) {        super(null);        this.source = source;        this.callback = callback;        setAuthenticated(false);    }    public ThirdPartyAuthenticationToken(Object principal, Object credentials, Collection authorities) {        super(authorities);        this.principal = principal;        this.credentials = credentials;        super.setAuthenticated(true);    }    @Override    public Object getPrincipal() {        return principal;    }    @Override    public Object getCredentials() {        return credentials;    }    public Object getCallback() {        return callback;    }    public Object getSource() {        return source;    }}
第三方统一登录认证逻辑(ThirdPartyAuthenticationProvider)
package com.mxy.security.justauth;import com.alibaba.fastjson.JSONObject;import com.mxy.common.core.constant.Constants;import com.mxy.common.core.entity.SelfUserEntity;import com.mxy.common.core.entity.SysRole;import com.mxy.common.core.entity.SysUser;import com.mxy.common.core.entity.SysUserRole;import com.mxy.common.core.utils.IPUtils;import com.mxy.common.core.utils.RedisUtil;import com.mxy.common.core.utils.ServletUtils;import com.mxy.common.log.enums.OperType;import com.mxy.security.security.service.SelfUserDetailsService;import com.mxy.system.service.SysUserService;import com.mxy.system.utils.LogUtil;import lombok.extern.slf4j.Slf4j;import me.zhyd.oauth.model.AuthCallback;import me.zhyd.oauth.model.AuthResponse;import me.zhyd.oauth.model.AuthUser;import me.zhyd.oauth.request.AuthRequest;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.AuthenticationProvider;import org.springframework.security.authentication.BadCredentialsException;import org.springframework.security.authentication.LockedException;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.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.*;/** * 第三方统一登录认证逻辑 */@Slf4j@Componentpublic class ThirdPartyAuthenticationProvider implements AuthenticationProvider {    @Autowired    private SelfUserDetailsService selfUserDetailsService;    @Autowired    private SysUserService sysUserService;    @Autowired    private RedisUtil redisUtil;    @Resource    private AuthUtil authUtil;    @Resource    private BCryptPasswordEncoder bCryptPasswordEncoder;    private Random random = new Random();    /**     * 第三方统一登录认证逻辑     */    @Override    public Authentication authenticate(Authentication authentication) throws AuthenticationException {        ThirdPartyAuthenticationToken token = (ThirdPartyAuthenticationToken) authentication;        String source = (String) token.getSource();        AuthCallback callback = (AuthCallback) token.getCallback();        log.info("------------进入" + source + "认证逻辑, callback params:" + JSONObject.toJSONString(callback));        AuthRequest authRequest = authUtil.getAuthRequest(source);        AuthResponse response = authRequest.login(callback);        if (response.getCode() == 5000) {            // 认证失败            throw new BadCredentialsException(source + "认证失败");        }        AuthUser authUser = (AuthUser) response.getData();        log.info("------------认证用户:{}", authUser);        // 根据 uuid 查询用户信息        SelfUserEntity userInfo = selfUserDetailsService.getUserInfoByUuid(authUser.getUuid());        if (userInfo == null) {            // 自动注册            userInfo = doRegister(authUser);        }        if (Constants.USER_STATE_TWO.equals(userInfo.getStatus())) {            LogUtil.saveLog("该账号已冻结[" + userInfo.getRelName() + "]", 99);            throw new LockedException("该账号已冻结");        }        // 角色集合        Set authorities = new HashSet<>();        // 查询用户角色        List sysRoleList = sysUserService.selectSysRoleByUserId(userInfo.getUserId());        for (SysRole sysRole : sysRoleList) {            authorities.add(new SimpleGrantedAuthority(sysRole.getRoleKey()));        }        userInfo.setAuthorities(authorities);        ThirdPartyAuthenticationToken authenticationResult = new ThirdPartyAuthenticationToken(userInfo, userInfo.getUserId(), userInfo.getAuthorities());        authenticationResult.setDetails(token.getDetails());        return authenticationResult;    }    /**     * 账号注册     **/    public SelfUserEntity doRegister(AuthUser authUser) {        SelfUserEntity selfUser = new SelfUserEntity();        SysUser sysUser = new SysUser();        sysUser.setNickName(authUser.getNickname());        sysUser.setUsername(authUser.getSource() + (random.nextInt(89999999) + 10000000));        String password = String.valueOf(random.nextInt(899999) + 100000);        sysUser.setPassword(bCryptPasswordEncoder.encode(password));        sysUser.setAvatar(authUser.getAvatar());        sysUser.setRegistrationType(authUser.getSource());        sysUser.setUuid(authUser.getUuid());        sysUser.setLoginCount(0);        sysUser.setIpSource(IPUtils.getClientIp(Objects.requireNonNull(ServletUtils.getRequest())));        // 2-男        sysUser.setSex("2".equals(authUser.getRawUserInfo().getString("gender_type")) ? "0" : "1");        sysUser.setCreateUser("system");        sysUser.setRemark(authUser.getSource() + "首次注册默认密码为:" + password);        sysUser.setLoginDate(new Date());        sysUser.setUserType("2");        sysUser.insert();        // 新增用户角色关系        SysUserRole sysUserRole = new SysUserRole();        sysUserRole.setUserId(sysUser.getUserId());        // 游客        sysUserRole.setRoleId("2");        sysUserRole.insert();        BeanUtils.copyProperties(sysUser, selfUser);        selfUser.setRelName(sysUser.getNickName());        LogUtil.saveNoLoginLog("账号注册(" + authUser.getSource() + ")", JSONObject.toJSONString(sysUser), OperType.REGISTRATION.ordinal());        return selfUser;    }    /**     * 判断是上面 authenticate 方法的 authentication 参数,是哪种类型     * Authentication 是个接口,实现类有很多,目前我们最熟悉的就是 ThirdPartyAuthenticationToken、UsernamePasswordAuthenticationToken     * 很明显,我们只支持 ThirdPartyAuthenticationToken,因为它封装的是TOKEN OPENID     *     * @param authentication     * @return     */    @Override    public boolean supports(Class authentication) {        return (ThirdPartyAuthenticationToken.class.isAssignableFrom(authentication));    }}

关键词: