package com.wx.server.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yitter.idgen.YitIdHelper;
import com.wx.server.pojo.Company;
import com.wx.server.pojo.User;
import com.wx.server.service.ICompanyService;
import com.wx.server.service.IUserService;
import com.wx.server.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@Controller
@RequestMapping("/auth")
@Slf4j
@SuppressWarnings("all")
public class AuthController {
@Autowired
private ICompanyService companyService;
@Autowired
private IUserService userService;
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("/code")
public String sendCode(HttpServletRequest request, Model model) {
try {
//解析请求
OAuthAuthzRequest oathReq = new OAuthAuthzRequest(request);
//获取到客户端的id
String clientId = oathReq.getClientId();
if (clientId == null) return "redirect:/error";
Company company = companyService.getOne(new QueryWrapper<Company>().lambda().eq(Company::getClientId, clientId), false);
//如果客户端跟我们没有合作
if (company == null) return "redirect:/error";
model.addAttribute("redirect_uri", oathReq.getRedirectURI());
model.addAttribute("company_info", company);
} catch (Exception e) {
return "error";
}
//跳到认证登录页
return "login";
}
@PostMapping("/doLogin")
public String doLogin(User user, String redirect_uri, Model model) {
//用户登录
User one = userService.getOne(new QueryWrapper<User>().lambda()
.eq(User::getAccount, user.getAccount())
.eq(User::getPassword, user.getPassword()));
//登录失败
if (one == null) return "redirect:/error";
//生成一个雪花id
long snowId = YitIdHelper.nextId();
//将需要的数据放到缓存中
//1.用作等会需要的判断,判断用户进行授权的请求是否来源与后端
//2.将用户的数据放入到缓存中,避免在前端暴露
redisTemplate.opsForValue().set("request:" + snowId, redirect_uri, 5, TimeUnit.MINUTES);
redisTemplate.opsForValue().set("user:" + snowId, one.getId());
model.addAttribute("snowId", snowId + "");
return "auth";
}
@GetMapping("/doAuth")
public String doAuth(HttpServletRequest request, String snowId) throws Exception {
//回调路径
Object obj = redisTemplate.opsForValue().get("request:" + snowId);
if (obj == null) {
return "redirect:/error";
}
//request:123456
String userId = redisTemplate.opsForValue().get("user:" + snowId).toString();
String code = getCode();
redisTemplate.opsForValue().set("code:" + code, userId, 5, TimeUnit.MINUTES);
//获取构建响应的对象
OAuthASResponse.OAuthAuthorizationResponseBuilder builder =
OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_OK);
builder.setCode(code);
String redirectURI = obj.toString();
OAuthResponse oauthResp = builder.location(redirectURI).buildQueryMessage();
//形成路径路径拼接效果 http://localhost:80/client/callback?code=xx
String uri = oauthResp.getLocationUri();
// redirect:/client/callback?code=xx
return "redirect:" + uri;
}
/**
* 生成授权码方法
*/
public String getCode() {
Random r = new Random();
String code = "";
for (int i = 0; i < 8; ++i) {
int temp = r.nextInt(52);
char x = (char) (temp < 26 ? temp + 97 : (temp % 26) + 65);
code += x;
}
return code;
}
@PostMapping("/token")
public HttpEntity getAccessToken(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {
//OAuthTokenRequest解析请求
OAuthTokenRequest tokenReq = new OAuthTokenRequest(request);
//获得客户端的信息
String clientId = tokenReq.getClientId();
String clientSecret = tokenReq.getClientSecret();
Company company = companyService.getOne(new QueryWrapper<Company>().lambda().eq(Company::getClientId, clientId).eq(Company::getClientSecret, clientSecret), false);
//去数据库做查询
if (company != null) {
//做授权码的判断
String code = tokenReq.getCode();
//将授权码带入到缓存中查看是否有对应的数据
String userId = redisTemplate.opsForValue().get("code:" + code).toString();
if(userId==null){
System.out.println("授权码可能过期或者伪造了");
return null;
}
String openId = userService.getById(userId).getOpenId();
String token = new JwtUtils().generateToken(openId);
//构造保护令牌的响应对象
OAuthResponse oAuthResponse = OAuthASResponse
.tokenResponse(HttpServletResponse.SC_OK)
.setAccessToken(token)
.buildJSONMessage();
return new ResponseEntity(oAuthResponse.getBody(), HttpStatus.valueOf(oAuthResponse.getResponseStatus()));
}
return null;
}
@GetMapping("/userinfo")
@ResponseBody
public Object getUserInfo(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {
//OAuthAccessResourceRequest解析请求
OAuthAccessResourceRequest oAuthAccessResourceRequest = new OAuthAccessResourceRequest(request, ParameterStyle.HEADER);
//请求头中获取令牌
String token = oAuthAccessResourceRequest.getAccessToken();
//判断令牌是否是我发给你的
String openId = new JwtUtils().getOpenIdFromToken(token);
if (openId == null) {
return null;
}
User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getOpenId, openId));
return user;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
OAuth2.0代码模拟实现
共34个文件
java:23个
ftl:6个
xml:3个
0 下载量 93 浏览量
2023-12-26
16:51:00
上传
评论
收藏 27KB ZIP 举报
温馨提示
OAuth2.0模拟实现代码
资源推荐
资源详情
资源评论
收起资源包目录
Oauth.zip (34个子文件)
pom.xml 3KB
wx-server
pom.xml 1KB
src
main
resources
templates
login.ftl 569B
auth.ftl 292B
error.ftl 196B
application.yml 347B
java
com
wx
server
WxServerApplication.java 2KB
mapper
UserMapper.java 240B
CompanyMapper.java 249B
controller
CompanyController.java 254B
UserController.java 248B
AuthController.java 7KB
pojo
Company.java 819B
User.java 1KB
service
IUserService.java 184B
ICompanyService.java 193B
impl
UserServiceImpl.java 374B
CompanyServiceImpl.java 395B
util
JwtUtils.java 3KB
config
MySQLGenerator.java 3KB
zking-server
pom.xml 771B
src
main
resources
templates
index.ftl 127B
login.ftl 437B
phone.ftl 190B
application.yml 291B
java
com
zking
server
mapper
ZkingUserMapper.java 261B
controller
GetAuthorizationController.java 4KB
ZkingUserController.java 262B
pojo
User.java 710B
ZkingUser.java 693B
service
impl
ZkingUserServiceImpl.java 421B
IZkingUserService.java 205B
ZkingApplication.java 407B
config
MySQLGenerator.java 3KB
共 34 条
- 1
资源评论
君易--鑨
- 粉丝: 821
- 资源: 16
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Python和PyTorch框架完成的一个手写数字识别实验源码(带MINIST手写数字数据集)+详细注释(高分项目)
- 基于Matlab在MNIST数据集上利用CNN完成手写体数字识别任务,并实现单层CNN反向传播算法+源代码+文档说明(高分项目)
- NVIDIA驱动、CUDA和Pytorch及其依赖
- html动态爱心代码一(附源码)
- c40539bc-071a-486c-9d52-9d0c18d62dac 4.html
- 基于物理的非视域成像(NLOS)算法,利用了nerf+python源码+文档说明
- yuluer知更鸟.7z(1).001
- python课程设计-基于tensorflow实现的图文生成程序,数据集flickr30k-images+源代码+文档说明+截图
- python作业-基于Flickr30k数据集实现图像文本跨模态搜索python源码+数据集+测试界面+项目说明(高分课程设计)
- 基于Qt实现医院信息管理系统c++源码+文档说明+数据库(期末大作业)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功