若依框架现在很火,很多团队与个人都使用它。作者看了看它最新的代码,它的认证方式有所不同,前后台分离版本使用的是shiro(具体代码:https://gitee.com/y_project/RuoYi/tree/master/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro),微服务版本使用的是JWT(具体代码:https://gitee.com/y_project/RuoYi-Cloud/blob/master/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java#L44)。不过很多时候,我们的组织或公司都已经构建了自己的认证系统,这个时候如何把我们的若依开发的系统和我们的认证系统集成在一起呢。这篇文章就给出全过程保姆式的方法演示.
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.security.oauthgroupId>
<artifactId>spring-security-oauth2artifactId>
<version>${security.oauth2.version}version>
dependency>
oauth2认证服务器的配置:
访问/oauth/token使用参数列表如下,注意我们这个地方grant_type用的是password.
OAuth 2.0中常见的grant_type:
字段 | 取值 |
---|---|
client_id | |
client_secret | |
grant_type | password |
scope | |
username | |
password |
下面以前后台分离版本的若依为例。
<dependency>
<groupId>org.springframework.security.oauth.bootgroupId>
<artifactId>spring-security-oauth2-autoconfigureartifactId>
<version>2.0.1.RELEASEversion>
dependency>
同时我们对代码做些稍微的修改:
security:
oauth2:
client:
clientId: *****
clientSecret: *****
accessTokenUri: ${auth-server}/oauth/token
userAuthorizationUri: ${auth-server}/oauth/authorize
resource:
userInfoUri: ${auth-server}/system/user/get
redirectUri: *****
其中userInfoUri是认证服务器提供的获取用户信息的接口
// 登录方法
export function login(username, password, code, uuid) {
return root_request({
url: '/oauth/token',
method: 'post',
params: { username, password, code, uuid, client_id, client_secret, grant_type, scope }
})
}
上面的root_request是我们新建的一个axios实例,它访问的是认证服务器,而不是ruoyi的后台
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: '/cgroot',
// 超时
timeout: 10000
})
devServer: {
host: '0.0.0.0',
port: port,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
},
['/cgroot']: {
target: `http://localhost:8880`,
changeOrigin: true,
pathRewrite: {
['^' + '/cgroot']: ''
}
}
},
disableHostCheck: true
},
/**
* 获取用户
**/
public static LoginUser getLoginUser()
{
try
{
OAuth2Authentication authentication = (OAuth2Authentication)getAuthentication();
Map<String, Object> userMap =
(Map<String, Object>) ((Map<String, Object>) authentication
.getUserAuthentication().getDetails()).get("data");
SysUser user = new SysUser();
Integer userId = (Integer) userMap.get("userId");
Integer proxyId = (Integer) userMap.get("proxyId");
String userName = (String) userMap.get("userName");
String avatar = (String) userMap.get("avatar");
String phonenumber = (String) userMap.get("phonenumber");
String email = (String) userMap.get("email");
String nickName = (String)userMap.get("nickName");
user.setUserId(Long.parseLong(String.valueOf(userId)));
user.setNickName(nickName);
user.setAvatar(avatar);
user.setPhonenumber(phonenumber);
user.setEmail(email);
user.setUserName(userName);
user.setProxyId(Long.parseLong(String.valueOf(proxyId)));
LoginUser loginUser = new LoginUser();
loginUser.setUser(user);
return loginUser;
}
catch (Exception e)
{
throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
}
}
这样便实现了ruoyi开发的系统与我们的第三方认证服务的对接。当然上面实现的是通过grant_type为password方式获取token,如果通过authorization_code获取token的话,上面的login方法里面需要用到重定向回来得到的code
上面的实现的关键是EnableOAuth2Sso这个注解,EnableOAuth2Sso是一个Spring Security的注解,用于在基于OAuth2的单点登录(SSO)流程中启用OAuth2 SSO支持。它实现在SpringSecurityFilterChain过滤器链上添加
OAuth2ClientAuthenticationProcessingFilter这个用于登录认证的Filter。它拦截用户的请求,并通过access_token获取认证服务器上的用户信息,并创建Authentication登录后凭证,并完在这里插入图片描述
成principal存储,让人感觉像ruoyi直接访问数据库拿到用户信息一样。
https://www.cnblogs.com/trust-freedom/p/12002089.html(EnableOAuth2Sso原理)
https://www.rfc-editor.org/rfc/rfc6749 (OAuth2 RFC)