shiro项目采用ruoyi,OAuth采用pig 若依:https://gitee.com/y_project/RuoYi pig:https://gitee.com/log4j/pig 采用OAuth授权码模式(authorization-code)1.流程简介:
①:若依配置好以后,点击链接(ip:端口/sso/login)进入pig-auth(统一认证中心)
②:在统一认证中心输入用户名,密码后,点击登录,进入统一认证中心的AuthorizationEndpoint的/oauth/authorize,并且返回code
③:若依拿到code之后进行处理,headers加入Authorization:Basic Base64(Base64指的是对clientId和clientSecret的编码),Content-Type:application/x-www-form-urlencoded),处理后请求统一认证中心的/oauth/token接口,返回access_token 和user_name等一系列信息
④:若依拿到access_token后,进行处理并访问统一认证中心的/oauth/check_token接口,统一认证接口返回用户信息
⑤:若依把统一用户中心查询到的用户信息,在本库查询后,把一些信息放入SimpleAuthenticationInfo,登录成功
2.项目集成 ①:集成若依项目,项目地址:https://gitee.com/y_project/RuoYipig增加客户端(sys_oauth_client_details 表直接增加 )
INSERT INTO `sys_oauth_client_details`(`client_id`, `resource_ids`, `client_secret`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`, `tenant_id`) VALUES ('ruoyi', NULL, 'ruoyi', 'server', 'refresh_token,authorization_code', 'http://localhost:80/sso/login', NULL, 43200, 2592001, NULL, 'true', 1);
②:在若依中增加pom依赖
com.pig4cloud.shiro sso-sdk0.0.9
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PHzYJWdL-1651893031265)(C:UserswangyjAppDataLocalTemp1650959750177.png)]
③:ruoyi-admin/application.yml 配置认证信息oauth2:
client:
client-id: ruoyi
client-secret: ruoyi
target-uri: http://localhost:${server.port}/ #登录后跳转到首页的地址
logout-uri: ${oauth2.client.target-uri} # 退出后跳转的地址
sso-server-uri: http://127.0.0.1:3000 #pigx认证中心的地址
scope: server
④:在com.ruoyi.framework.shiro.realm增加OAuth2Realm逻辑
package com.ruoyi.framework.shiro.realm;
import com.pig4cloud.shiro.oauth.OAuth2SsoAuthenticationToken;
import com.pig4cloud.shiro.oauth.OAuth2SsoKit;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OAuth2Realm extends UserRealm {
@Autowired
private ISysUserService userService;
@Autowired
private OAuth2SsoKit auth2SsoKit;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
OAuth2SsoAuthenticationToken oAuth2SsoAuthenticationToken = (OAuth2SsoAuthenticationToken) token;
String username = auth2SsoKit.getUser(oAuth2SsoAuthenticationToken.getCode());
SysUser sysUser = userService.selectUserByLoginName(username);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes(sysUser.getSalt()), getName());
oAuth2SsoAuthenticationToken.setUsername(sysUser.getUserName());
oAuth2SsoAuthenticationToken.setPassword(sysUser.getPassword().toCharArray());
return info;
}
@Override
public CredentialsMatcher getCredentialsMatcher() {
return (token, info) -> true;
}
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof OAuth2SsoAuthenticationToken;
}
}
⑤:ShiroConfig 配置
把securityManager 的securityManager.setRealm(userRealm);替换成securityManager.setRealms(Arrays.asList(oAuth2Realm, userRealm));
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nsspc36I-1651893031267)(C:UserswangyjAppDataLocalTemp1650960066441.png)]
⑥:过滤器配置在
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
{
....
}
增加一行
filterChainDefinitionMap.put("/sso/login", "anon");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRGsVvR9-1651893031268)(C:UserswangyjAppDataLocalTemp1650960293529.png)]
⑦:退出逻辑 Ⅰ:增加下列代码@Autowired
OAuth2SsoKit auth2SsoKit;
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setLoginUrl(loginUrl);
logoutFilter.setAuth2SsoKit(auth2SsoKit);
return logoutFilter;
}
Ⅱ:把LogoutFilter做出改造
public class LogoutFilter extends LogoutFilter {
private String loginUrl;
private OAuth2SsoKit auth2SsoKit;
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
...
auth2SsoKit.logout();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Np1icHcH-1651893031269)(C:UserswangyjAppDataLocalTemp1650960583060.png)]
⑧:地址sso登录地址
// 例如:若依的端口是8089 http://localhost:8089/sso/login
获取授权码地址
org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint
http://localhost:3000/oauth/authorize?client_id=ruoyi&response_type=code&redirect_uri=你的前端地址
校验授权码返回accessToken,基本上拿到token算是登录成功了
org.springframework.security.oauth2.provider.endpoint.TokenEndpoint
// code是你获取的授权码(code=GYbbap) http://localhost:3000/oauth/token?grant_type=authorization_code&code=GYbbap&client_id=xdianyun&client_secret=xdianyun&redirect_uri=你的前端地址
验证token返回用户信息
org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint
http://127.0.0.1:3000/oauth/check_token?token=fd53c0e4-9804-44ac-bb74-52b007d60346
退出登录
http://127.0.0.1:3000/logout?redirect_url=你的前端地址3.一些小问题
①:获取的授权码重复
排查一下nginx的缓存问题,如expires 2h;这种注释掉
②:在你配置的client-id和client-secret正确无误的情况下,仍然跳转用户中心失败
排查一下你的nginx配置的认证中心的地址是否正确
③:第三方软件登录后无法退出或者两个第三方软件,一个登录上了,另外一个没有登录上
1:3000/logout?redirect_url=你的前端地址
### 3.一些小问题 ①:获取的授权码重复 排查一下nginx的缓存问题,如expires 2h;这种注释掉 ②:在你配置的client-id和client-secret正确无误的情况下,仍然跳转用户中心失败 排查一下你的nginx配置的认证中心的地址是否正确 ③:第三方软件登录后无法退出或者两个第三方软件,一个登录上了,另外一个没有登录上 排查一下nginx有无缓存



