自定义登录
实现SecurityProvider
首先需要实现com.basksoft.core.security.provider.JakartaSecurityProvider接口的实现类:
package com.basksoft.core.security.provider;
import jakarta.servlet.http.HttpServletRequest;
import com.basksoft.core.security.entity.User;
/**
* 登录用户相关接口
*/
public interface JakartaSecurityProvider {
/**
* 获取登录用户对象
* @param req HttpServletRequest
* @return 返回用户对象
*/
User getLoginUser(HttpServletRequest req);
/**
* 执行登录操作
* @param req HttpServletRequest
* @param account 账号
* @param password 密码
*/
void login(HttpServletRequest req, String account,String password);
/**
* 执行登出操作
* @param req HttpServletRequest
*/
void logout(HttpServletRequest req);
/** 重置缓存中的用户对象,对于一些第三方扩展用户缓存的当用户团队发生变化的时候会重置缓存中的用户对象,及时同步用
* @param req HttpServletRequest
* @param loginUser 登录用户对象
*/
void resetUser(HttpServletRequest req, User loginUser);
}
在该实现类中实现内部的三个方法。
BaskServer利用【SPI】扩展机制,你可以利用ServiceLoader定义一个JakartaSecurityProvider的扩展类并配置到系统中。 具体办法在项目的resources/META-INF/services下添加一个名称为com.basksoft.core.security.provider.JakartaSecurityProvider的文件 内容为:
test.MySecurityProvider
参考实现:
package test;
public class MySecurityProvider implements JakartaSecurityProvider {
private static final String LOGIN_USER="_baskserver_login_user";
@Override
public User getLoginUser(HttpServletRequest req) {
Object obj = req.getSession().getAttribute(LOGIN_USER);
if (obj!=null) {
return (User)obj;
} else {
return null;
}
}
@Override
public void login(HttpServletRequest req, String account, String password) {
//com.basksoft.core.database.model.User user = UserServiceManager.getUserService().validate(account, password);
//User loginUser = new DefaultUser(account, user.getUsername(), user.isEnable(), user.getTenants());
//TODO: 返回BaskServer的com.basksoft.core.security.entity.User对象,也可以用Bask的默认实现类com.basksoft.core.security.entity.DefaultUser
//注意返回的用户对象的enabled为true,并且tenants信息要正确,用以区分用户所属的团队,从而支持多租户场景的使用,如果没有可以设置一个固定值
req.getSession().setAttribute(LOGIN_USER, loginUser);
}
@Override
public void logout(HttpServletRequest req) {
req.getSession().removeAttribute(LOGIN_USER);
}
@Override
public void resetUser(HttpServletRequest req, User loginUser) {
req.getSession().setAttribute(LOGIN_USER, loginUser);
}
}
通过以上的方法解决BaskServer Console的用户登录登出和用户信息获取的逻辑。
其中getLoginUser方法需要返回com.basksoft.core.security.entity.User对象,定义如下:
public class User {
/**
* 用户账号
*/
private String account;
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 用户邮箱
*/
private String email;
/**
* 是否启用
*/
private boolean enable;
/**
* 备注
*/
private String desc;
/**
* 租户
*/
private List<Tenant> tenants;
}
这个对象有一个getTenants方法,这个方法是用来获取用户所属的团队列表。该逻辑关系是存储在BaskServer的系统表中的,所以我们可以通过一个特殊的方法获取用户对应的团队列表:
List<Tenant> tenants = com.basksoft.core.database.manager.tenant.TenantManager.ins.newQuery.list(String account);
要确保getLoginUser返回的用户对象中有团队列表(Tenant)信息,否则这个用户无法访问BaskServer中的任何资源。
如果你的租户不是在BaskServer中创建的,尤其是系统集成框架下,你必须在创建用户对象时自己初始化这个对象的tenants信息
扩展UserService
UserService接口是BaskServer中获取用户信息对应的接口类。 BaskServer利用【SPI】实现用户服务类的扩展。 实现方法参考:UserService
在登录页面对应的登录逻辑的处理代码中调用如下代码,完成BaskReport的用户登录:
com.basksoft.core.security.SecurityUtils.getJaraktaSecurityProvider().login(request, account, password);