fast-security-starter 1.0
目标
基于jwt认证机制,角色匹配url规则,实现认证,鉴权的快速集成
介绍
对于认证,鉴权,shiro与spring-security较为成熟,但是学习成本较高。 所以想做一个可以快速集成spring-security的拓展包,理想化是拿来即用, 因个人功底有限,现只能做到基本的快速使用,对于单服务项目,基于springboot,可以快速集成.
基本流程为:用户登陆,获取一个token,在token生命周期内,访问业务接口, 则需要在header头带上此token
集成指南
1.mvn package 打成jar包导入到自己的项目,或者install到自己的私服仓库 优化一段时间后,会考虑推送到maven仓库
2.基本配置,在application.yml中进行基本配置 参考类:AuthProperties 以下为例
fast: auth: # 默认所有的接口都需要鉴权,如需配置不需要鉴权的url 则在此以ant风格配置 antUrl: /o/**, /open/** # jwt有效期 单位:天 默认 expireDays: 5 # jwt生成的key secret: expireDays # 登陆地址 默认 loginUrl: login # 登陆方式 loginMethod: POST # 业务请求jwt key值 jwtHeaderKey: Authorization # 业务请求jwt value值前缀 jwtHeaderValueStart: Bearer
3.登陆 登陆,也就是认证,获取token签名,一般无非两个组成:登陆参数与登陆逻辑 3-1 登陆参数 现今各种系统登陆方式五花八门,比如手机号,用户名密码,邮箱等等。 抽象为接口:ILoginBo,如果你的登陆是username和password,那么可以使用默认实现类:DefaultLoginBo 如果不满足,请实现此接口自定义登陆参数类,例:
@Data public class CustomLoginBo implements ILoginBo { private String username; private String password; //验证码 private String code; }
3-2 登陆逻辑 每个系统的登陆逻辑都不一样,请自定义类继承抽象类AbstractLoginAdapter,需要实现两个方法,例:
public class CustomLogin extends AbstractLoginAdapter<CustomLoginBo> {//泛型要指定为登陆类 //指定登陆参数类的class 因为后面序列化需要用,回头会想想优化可以去掉此方法 @Override public Class<CustomLoginBo> getLoginBoClass() { return CustomLoginBo.class; } /** * 登陆逻辑 * @param loginBo 定义的登陆类 * @return JwtUser 登陆用户的信息 * @throws LoginException 登陆异常,请抛出此类,此类的 */ @Override public JwtUser login(CustomLoginBo loginBo) throws LoginException { if (loginBo.getUsername().equals("admin")) { //jwtUser类为指定的登陆用户信息类 JwtUser user = new JwtUser(); //请将用户信息放入detail 就像将用户信息放到servlet的session中 user.setDetails(loginBo); //设置用户所属的角色标识集合,一般为角色id,如果你的系统有角色,有部门,可以这样 role_角色id, dept_部门id user.setRoles(Arrays.asList(new String[]{"roleId"})); //登陆成功 return user; } else { //验证的地方,使用LoginException异常类,参数DefaultAuthResult 可以替换为你的项目定义的统一的接口返回值类 throw new LoginException(new DefaultAuthResult(300, "用户名不存在")); } } } 登陆成功,客户端会收到返回值登陆成功时,data值固定有user和token,details为你的用户model,roles为角色id集合, 至于最外层的data是固定key,code与msg,可以自定义,下文会有介绍 { "code": 0, "data": { "user": { "details": { "password": "admin", "username": "admin" }, "roles": [ "admin" ] }, "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJub25lIiwibmJmIjoxNTU3ODYyNTE1LCJpc3MiOiJub25lIiwib3duX3BhcmFtcyI6eyJyb2xlcyI6WyJhZG1pbiJdLCJkZXRhaWxzIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6ImFkbWluIn19LCJleHAiOjE1NTgzMjMzMTUsImlhdCI6MTU1Nzg2MjUxNX0.pp7Dn0u2x1e05KagE-7rOK2es9tjR_qqJ-IyVQ4a0Ew" }, "msg": "认证成功" }
4.访问业务接口 登陆成功后,如需访问业务接口,请在header中加入 Authorization,值为 Bearer + 上一步的token, 其中Authorization 与 Bearer,可通过配置文件自定义覆盖
5.鉴权 //需自定义类继承AbstractAuthAdapter抽象类
public class CustomAuth extends AbstractAuthAdapter { /** * 提供url所需权限 * @param url 请求的url */ @Override protected List<String> getRolesByRequestUrl(String url, HttpServletRequest request, HttpServletResponse response) { //如无需url鉴权,请直接返回null return null; //如需鉴权,在此处根据url去数据库或者缓存中,查询到该url所对应的所有角色id集合 roleIdList,并返回 //框架会根据当前请求的用户角色集合与roleIdList是否有并集,有则通过,访问业务接口,无则返回权限错误 } }
6.返回值处理 因为不同的团队,不同系统,接口统一返回值格式各不一样,因此返回值这里也做了自定义扩展。 默认格式为:
{ "code": 0, "msg": "请求成功", "data": "业务数据" } 如果与你预期的不一致,可以自定义,但是data字段不允许自定义(后面会考虑优化) 可以将你的接口返回值类继承AuthResultAdapet类,加入你的自定义字段,可参考我写的默认实现: @Data public class DefaultAuthResult extends AuthResultAdapet { private int code; private String msg; public DefaultAuthResult() { super(null); } public DefaultAuthResult(int code, String msg) { super(null); this.code = code; this.msg = msg; } @Override public AuthResultAdapet loginSuccess() { return Contant.loginSuccess; } @Override public AuthResultAdapet loginFail() { return Contant.loginFail; } @Override public AuthResultAdapet noToken() { return Contant.noToken; } @Override public AuthResultAdapet acessDenied() { return Contant.acessDenied; } //此处为框架本身的几处需要返回值的地方 public static class Contant { public static final DefaultAuthResult loginSuccess = new DefaultAuthResult(0, "登陆成功"); public static final DefaultAuthResult loginFail = new DefaultAuthResult(103, "登陆失败"); public static final DefaultAuthResult noToken = new DefaultAuthResult(401, "请登陆"); public static final DefaultAuthResult acessDenied = new DefaultAuthResult(403, "凭证无效"); } }
7.启用,将刚才配置的三个类,加入容器中,即可启动测试:
@Configuration public class SecurityConfig extends WebSecurityConfig { @Bean public ILogin login() { return new CustomLogin(); } @Bean public IAuth auth() { return new CustomAuth(); } @Bean public AuthResultAdapet authResult(){ return new DefaultAuthResult(); } }
以上为基本使用,项目中有demo,后面会进行优化,如有疑问,不足的地方,希望随时指出,共同进步。
作者
luci yuyanan 邮箱:575873200@qq.com git:https://gitee.com/luci-fast/luci-fast-security