mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
feat: sa-token-quick-login 插件支持 Http Basic 方式通过认证
This commit is contained in:
parent
18ab60d4d2
commit
a7f178da53
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.dev33.satoken.httpauth.basic;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.SaTokenException;
|
||||||
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token Http Basic 账号
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 1.41.0
|
||||||
|
*/
|
||||||
|
public class SaHttpBasicAccount {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账号
|
||||||
|
*/
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param username 账号
|
||||||
|
* @param password 密码
|
||||||
|
*/
|
||||||
|
public SaHttpBasicAccount(String username, String password) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param usernameAndPassword 账号和密码,冒号隔开
|
||||||
|
*/
|
||||||
|
public SaHttpBasicAccount(String usernameAndPassword) {
|
||||||
|
if(SaFoxUtil.isEmpty(usernameAndPassword)) {
|
||||||
|
throw new SaTokenException("UsernameAndPassword 不能为空");
|
||||||
|
}
|
||||||
|
String[] arr = usernameAndPassword.split(":");
|
||||||
|
if(arr.length != 2) {
|
||||||
|
throw new SaTokenException("UsernameAndPassword 格式错误,正确格式为:username:password");
|
||||||
|
}
|
||||||
|
this.username = arr[0];
|
||||||
|
this.password = arr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 账号
|
||||||
|
*
|
||||||
|
* @return username 账号
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 账号
|
||||||
|
*
|
||||||
|
* @param username 账号
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 密码
|
||||||
|
*
|
||||||
|
* @return password 密码
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 密码
|
||||||
|
*
|
||||||
|
* @param password 密码
|
||||||
|
*/
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SaHttpBasicAccount{" +
|
||||||
|
"username='" + username + '\'' +
|
||||||
|
", password='" + password + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -45,7 +45,7 @@ public class SaHttpBasicTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取浏览器提交的 Basic 参数 (裁剪掉前缀并解码)
|
* 获取浏览器提交的 Http Basic 参数 (裁剪掉前缀并解码)
|
||||||
* @return 值
|
* @return 值
|
||||||
*/
|
*/
|
||||||
public String getAuthorizationValue() {
|
public String getAuthorizationValue() {
|
||||||
@ -61,7 +61,19 @@ public class SaHttpBasicTemplate {
|
|||||||
// 裁剪前缀并解码
|
// 裁剪前缀并解码
|
||||||
return SaBase64Util.decode(authorization.substring(6));
|
return SaBase64Util.decode(authorization.substring(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Http Basic 账号密码对象
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public SaHttpBasicAccount getHttpBasicAccount() {
|
||||||
|
String authorizationValue = getAuthorizationValue();
|
||||||
|
if(authorizationValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new SaHttpBasicAccount(authorizationValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对当前会话进行 Basic 校验(使用全局配置的账号密码),校验不通过则抛出异常
|
* 对当前会话进行 Basic 校验(使用全局配置的账号密码),校验不通过则抛出异常
|
||||||
*/
|
*/
|
||||||
|
@ -32,13 +32,21 @@ public class SaHttpBasicUtil {
|
|||||||
public static SaHttpBasicTemplate saHttpBasicTemplate = new SaHttpBasicTemplate();
|
public static SaHttpBasicTemplate saHttpBasicTemplate = new SaHttpBasicTemplate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取浏览器提交的 Basic 参数 (裁剪掉前缀并解码)
|
* 获取浏览器提交的 Http Basic 参数 (裁剪掉前缀并解码)
|
||||||
* @return 值
|
* @return 值
|
||||||
*/
|
*/
|
||||||
public static String getAuthorizationValue() {
|
public static String getAuthorizationValue() {
|
||||||
return saHttpBasicTemplate.getAuthorizationValue();
|
return saHttpBasicTemplate.getAuthorizationValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Http Basic 账号密码对象
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static SaHttpBasicAccount getHttpBasicAccount() {
|
||||||
|
return saHttpBasicTemplate.getHttpBasicAccount();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对当前会话进行 Basic 校验(使用全局配置的账号密码),校验不通过则抛出异常
|
* 对当前会话进行 Basic 校验(使用全局配置的账号密码),校验不通过则抛出异常
|
||||||
*/
|
*/
|
||||||
|
@ -114,6 +114,12 @@ public class TestController {
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
也可以通过 Http Basic 的方式直接进行认证 (一般需要在专门的 API 测试工具下才能正常测试,浏览器会自动忽略@之前的信息)
|
||||||
|
|
||||||
|
``` url
|
||||||
|
http://sa:123456@localhost:8081/
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### 可配置信息
|
### 可配置信息
|
||||||
你可以在yml中添加如下配置 (所有配置都是可选的)
|
你可以在yml中添加如下配置 (所有配置都是可选的)
|
||||||
|
@ -17,10 +17,13 @@ package cn.dev33.satoken.quick;
|
|||||||
|
|
||||||
import cn.dev33.satoken.context.SaHolder;
|
import cn.dev33.satoken.context.SaHolder;
|
||||||
import cn.dev33.satoken.filter.SaServletFilter;
|
import cn.dev33.satoken.filter.SaServletFilter;
|
||||||
|
import cn.dev33.satoken.httpauth.basic.SaHttpBasicAccount;
|
||||||
|
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||||
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
||||||
import cn.dev33.satoken.router.SaRouter;
|
import cn.dev33.satoken.router.SaRouter;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
import cn.dev33.satoken.util.SaTokenConsts;
|
import cn.dev33.satoken.util.SaTokenConsts;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -75,11 +78,27 @@ public class SaQuickRegister {
|
|||||||
.match(SaFoxUtil.convertStringToList(SaQuickManager.getConfig().getInclude()))
|
.match(SaFoxUtil.convertStringToList(SaQuickManager.getConfig().getInclude()))
|
||||||
.notMatch(SaFoxUtil.convertStringToList(SaQuickManager.getConfig().getExclude()))
|
.notMatch(SaFoxUtil.convertStringToList(SaQuickManager.getConfig().getExclude()))
|
||||||
.check(r -> {
|
.check(r -> {
|
||||||
// 未登录时直接转发到login.html页面
|
|
||||||
if (SaQuickManager.getConfig().getAuth() && ! StpUtil.isLogin()) {
|
// 如果已关闭认证要求,则直接通过
|
||||||
SaHolder.getRequest().forward("/saLogin");
|
if (!SaQuickManager.getConfig().getAuth()) {
|
||||||
SaRouter.back();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果请求端提供了 Http Basic 认证信息,那么直接使用此认证信息进行登录判断
|
||||||
|
SaHttpBasicAccount hba = SaHttpBasicUtil.getHttpBasicAccount();
|
||||||
|
if(hba != null) {
|
||||||
|
SaResult res = SaQuickManager.getConfig().doLoginHandle.apply(hba.getUsername(), hba.getPassword());
|
||||||
|
if(res.getCode() != SaResult.CODE_SUCCESS) {
|
||||||
|
SaRouter.back(res);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 未登录时直接转发到 login.html 页面
|
||||||
|
if (! StpUtil.isLogin()) {
|
||||||
|
SaHolder.getRequest().forward("/saLogin");
|
||||||
|
SaRouter.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package cn.dev33.satoken.quick.config;
|
package cn.dev33.satoken.quick.config;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.quick.function.DoLoginHandleFunction;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sa-quick 配置类 Model
|
* sa-quick 配置类 Model
|
||||||
*
|
*
|
||||||
@ -110,8 +115,27 @@ public class SaQuickConfig {
|
|||||||
public void setExclude(String exclude) {
|
public void setExclude(String exclude) {
|
||||||
this.exclude = exclude;
|
this.exclude = exclude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录处理函数
|
||||||
|
*/
|
||||||
|
public DoLoginHandleFunction doLoginHandle = (name, pwd) -> {
|
||||||
|
|
||||||
|
// 参数完整性校验
|
||||||
|
if(SaFoxUtil.isEmpty(name) || SaFoxUtil.isEmpty(pwd)) {
|
||||||
|
return SaResult.get(500, "请输入账号和密码", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 密码校验:将前端提交的 name、pwd 与配置文件中的配置项进行比对
|
||||||
|
if(name.equals(this.getName()) && pwd.equals(this.getPwd())) {
|
||||||
|
StpUtil.login(this.getName());
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
} else {
|
||||||
|
return SaResult.error("账号或密码输入错误");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SaQuickConfig{" +
|
return "SaQuickConfig{" +
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020-2099 sa-token.cc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package cn.dev33.satoken.quick.function;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 函数式接口:登录处理函数
|
||||||
|
*
|
||||||
|
* <p> 参数:账号、密码 </p>
|
||||||
|
* <p> 返回:登录结果 </p>
|
||||||
|
*
|
||||||
|
* @author click33
|
||||||
|
* @since 1.41.0
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface DoLoginHandleFunction extends BiFunction<String, String, SaResult> {
|
||||||
|
|
||||||
|
}
|
@ -16,9 +16,6 @@
|
|||||||
package cn.dev33.satoken.quick.web;
|
package cn.dev33.satoken.quick.web;
|
||||||
|
|
||||||
import cn.dev33.satoken.quick.SaQuickManager;
|
import cn.dev33.satoken.quick.SaQuickManager;
|
||||||
import cn.dev33.satoken.quick.config.SaQuickConfig;
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
|
||||||
import cn.dev33.satoken.util.SaResult;
|
import cn.dev33.satoken.util.SaResult;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -56,21 +53,7 @@ public class SaQuickController {
|
|||||||
@PostMapping("/doLogin")
|
@PostMapping("/doLogin")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public SaResult doLogin(@RequestParam("name") String name, @RequestParam("pwd") String pwd) {
|
public SaResult doLogin(@RequestParam("name") String name, @RequestParam("pwd") String pwd) {
|
||||||
|
return SaQuickManager.getConfig().doLoginHandle.apply(name, pwd);
|
||||||
// 参数完整性校验
|
|
||||||
if(SaFoxUtil.isEmpty(name) || SaFoxUtil.isEmpty(pwd)) {
|
|
||||||
return SaResult.get(500, "请输入账号和密码", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 密码校验:将前端提交的 name、pwd 与配置文件中的配置项进行比对
|
|
||||||
SaQuickConfig config = SaQuickManager.getConfig();
|
|
||||||
if(name.equals(config.getName()) && pwd.equals(config.getPwd())) {
|
|
||||||
StpUtil.login(config.getName());
|
|
||||||
return SaResult.get(200, "ok", StpUtil.getTokenInfo());
|
|
||||||
} else {
|
|
||||||
// 校验失败
|
|
||||||
return SaResult.get(500, "账号或密码输入错误", null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user