赞
踩
1.认证鉴权服务,注册中心,认证中心,鉴权中心;
2.用户,角色,权限表设计,数据库视图的使用;
3.项目中的应用,使用自定义注解+拦截器;
4.枚举类型的json化, @JsonFormat(shape = JsonFormat.Shape.OBJECT) @Getter
https://gitee.com/pet365/springboot-privs-token
用户和权限之间关系(多对多)
中间内容: 角色
(本系统中: user—》角色(one-to-Many)
-- 用户角色-权限模型
SELECT
user_owner.username,privs_role_tab.role_name,privs_tab.privs_name
FROM user_owner
LEFT JOIN privs_role_tab ON user_owner.user_role = privs_role_tab.role_id
LEFT JOIN privs_relationship_tab ON privs_relationship_tab.rp_role = privs_role_tab.role_id
LEFT JOIN privs_tab ON privs_tab.privs_id=privs_relationship_tab.rp_privs
https://gitee.com/pet365/springboot-privs-token
PrivsCheck.java文件
package com.tianju.auth.util;
import java.lang.annotation.*;
/**
* 定义注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PrivsCheck {
String value() default "";
}
AuthInterceptor.java文件
package com.tianju.auth.interceptor; import cn.hutool.json.JSONUtil; import com.tianju.auth.dto.HttpResp; import com.tianju.auth.dto.ResultCode; import com.tianju.auth.util.JwtUtil; import com.tianju.auth.util.PrivsCheck; import io.jsonwebtoken.ExpiredJwtException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Date; @Component @Slf4j public class AuthInterceptor implements HandlerInterceptor { /** * * @param request 请求 * @param response 响应 * @param handler =====>handler====>:class org.springframework.web.method.HandlerMethod * com.tianju.auth.controller.UserController#findAllUsernames() * 类 的 findAllUsernames() 方法 * Method method = handlerMethod.getMethod();// controller里面的方法findAllUsernames 对象 * Annotation[] annotations = method.getDeclaredAnnotations();// 可以获得该方法上的所有注解 * @return 是否拦截 * @throws Exception token过期异常 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("token"); response.setContentType("text/html;charset=utf-8"); if (token==null){ // 如果没有token,返回false response.getWriter().write( JSONUtil.toJsonStr( HttpResp.results( ResultCode.USER_NOT_LOGIN_ERROR, new Date(),"用户没有登陆异常" ))); return false; } // 存在的用户,检验token是否过期 try { // 正常情况 String username = JwtUtil.getClaim(token, "username"); String privs = JwtUtil.getClaim(token, "privs"); // 判断是否能够访问当前的方法 log.info("用户权限{}",privs); // handler:com.tianju.auth.controller.UserController#findAllUsernames() log.debug("handler:{}",handler); HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod();// controller里面的方法findAllUsernames 对象 Annotation[] annotations = method.getDeclaredAnnotations();// 可以获得该方法上的所有注解 /** * @org.springframework.web.bind.annotation.GetMapping(path=[], headers=[], name=, produces=[], params=[], value=[/findAllUsernames], consumes=[]) * @io.swagger.annotations.ApiOperation(code=200, notes=, hidden=false, authorizations=[@io.swagger.annotations.Authorization(scopes=[@io.swagger.annotations.AuthorizationScope(scope=, description=)], value=)], httpMethod=, tags=[查询所有用户名], extensions=[@io.swagger.annotations.Extension(name=, properties=[@io.swagger.annotations.ExtensionProperty(parseValue=false, name=, value=)])], responseHeaders=[@io.swagger.annotations.ResponseHeader(name=, responseContainer=, description=, response=class java.lang.Void)], response=class java.lang.Void, responseReference=, responseContainer=, produces=, nickname=, ignoreJsonView=false, position=0, protocols=, consumes=, value=findAllUsernames) * @com.tianju.auth.util.PrivsCheck(value=findAllUsernames) */ // for (Annotation annotation: annotations) { // /** // * @org.springframework.web.bind.annotation.GetMapping(path=[], headers=[], name=, produces=[], params=[], value=[/findAllUsernames], consumes=[]) // * @io.swagger.annotations.ApiOperation(code=200, notes=, hidden=false, authorizations=[@io.swagger.annotations.Authorization(scopes=[@io.swagger.annotations.AuthorizationScope(scope=, description=)], value=)], httpMethod=, tags=[查询所有用户名], extensions=[@io.swagger.annotations.Extension(name=, properties=[@io.swagger.annotations.ExtensionProperty(parseValue=false, name=, value=)])], responseHeaders=[@io.swagger.annotations.ResponseHeader(name=, responseContainer=, description=, response=class java.lang.Void)], response=class java.lang.Void, responseReference=, responseContainer=, produces=, nickname=, ignoreJsonView=false, position=0, protocols=, consumes=, value=findAllUsernames) // * @com.tianju.auth.util.PrivsCheck(value=findAllUsernames) // */ // } PrivsCheck annotation = method.getDeclaredAnnotation(PrivsCheck.class); System.out.println(annotation.value()); if (privs.contains(annotation.value())){ // 有此权限 return true; }else { response.getWriter().write( JSONUtil.toJsonStr( HttpResp.results( ResultCode.USER_ACCESS_ERROR, new Date(),"对不起权限不足" ))); return false; } }catch (ExpiredJwtException e){ // token过期 response.getWriter().write( JSONUtil.toJsonStr( HttpResp.results( ResultCode.USER_LOGIN_TOKEN_EXPIRED_ERROR, new Date(),"token过期" ))); return false; } } }
拦截器的配置AuthConfig.java文件
package com.tianju.auth.config; import com.tianju.auth.interceptor.AuthInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class AuthConfig implements WebMvcConfigurer { @Autowired private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/user/login"); } }
package com.tianju.auth.controller; import com.tianju.auth.dto.HttpResp; import com.tianju.auth.dto.ResultCode; import com.tianju.auth.entity.UserPrivs; import com.tianju.auth.service.IUserService; import com.tianju.auth.util.JwtUtil; import com.tianju.auth.util.PrivsCheck; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.List; @RestController @RequestMapping("/api/user") @Api(tags = "用户api接口") public class UserController { @Autowired private IUserService userService; @ApiOperation(value = "login",tags = "用户登录接口") @ApiImplicitParams({ @ApiImplicitParam(name = "username",value = "用户名",required = true), @ApiImplicitParam(name = "password",value = "密码",required = true) }) @GetMapping("/login") public HttpResp login(String username, String password, HttpServletResponse response){ List<UserPrivs> users = userService.login(username, password); StringBuilder privs = new StringBuilder(); users.forEach(userPrivs -> privs.append(userPrivs.getPrivsName()+",")); System.out.println("用户权限:"+privs); privs.deleteCharAt(privs.length()-1); String token = JwtUtil.createToken(username, privs.toString(), 1000 * 60); response.addHeader("token", token); return HttpResp.results(ResultCode.USER_LOGIN_SUCCESS,new Date(),username); } @GetMapping("/findAllUsernames") @ApiOperation(value = "findAllUsernames",tags = "查询所有用户名") // @PrivsCheck("findAllUsernames") @PrivsCheck("findX") // 设置一个没有的权限 public HttpResp findAllUsernames(){ List<String> allUsernames = userService.findAllUsernames(); return HttpResp.results(ResultCode.USER_QUERY_SUCCESS,new Date(),allUsernames); } }
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
package com.tianju.auth.dto; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; /** * 枚举类型,http请求的返回值 */ // 枚举类型的json化,需要有get方法 @JsonFormat(shape = JsonFormat.Shape.OBJECT) @Getter public enum ResultCode { BOOK_RUSH_SUCCESS(20010,"图书抢购成功"), BOOK_RUSH_ERROR(3001,"图书抢购失败"), LUA_SCRIPT_ERROR(3002,"Lua脚本操作失败"), USER_FIND_ERROR(40010,"非法请求,布隆过滤器不通过"), USER_FIND_SUCCESS(20010,"查询用户名成功"), USER_QUERY_SUCCESS(25010,"查询所有用户名成功"), USER_LOGIN_ERROR(40030,"用户登陆失败"), USER_NOT_LOGIN_ERROR(40040,"用户没有登陆异常"), USER_LOGIN_TOKEN_EXPIRED_ERROR(42040,"token已过期异常"), USER_ACCESS_ERROR(45040,"用户权限异常"), USER_LOGIN_SUCCESS(20020,"用户登陆成功"), ; @ApiModelProperty("状态码") private Integer code; @ApiModelProperty("提示信息") private String msg; private ResultCode(Integer code,String msg){ this.code =code; this.msg = msg; } }
@JsonFormat(timezone = “GMT+8”)
package com.tianju.auth.dto; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; /** * 返回给前端的响应 * @param <T> */ @ApiModel("DTO返回数据") @Data @NoArgsConstructor @AllArgsConstructor public class HttpResp<T> implements Serializable { private ResultCode resultCode; @ApiModelProperty("time") @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",timezone = "GMT+8") private Date time; @ApiModelProperty("results") private T result; public static <T> HttpResp <T> results( ResultCode resultCode, Date time, T results){ HttpResp httpResp = new HttpResp(); httpResp.setResultCode(resultCode); httpResp.setTime(time); httpResp.setResult(results); return httpResp; } }
package com.tianju.auth.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @TableName("user_privs_view") public class UserPrivs { @TableField("username") private String username; @TableField("password") private String password; @TableField("role_name") private String roleName; @TableField("privs_name") private String privsName; }
dao
package com.tianju.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tianju.auth.entity.UserPrivs;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<UserPrivs> {
}
1.认证鉴权服务,注册中心,认证中心,鉴权中心;
2.用户,角色,权限表设计,数据库视图的使用;
3.项目中的应用,使用自定义注解+拦截器;
4.枚举类型的json化, @JsonFormat(shape = JsonFormat.Shape.OBJECT) @Getter
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。