照搬了https://blog.csdn.net/WiLL_XS/article/details/104894724这篇文章的代码,先谢谢这位老哥,在这些代码的基础上根据自己的需求简化了很多

pom.xml:

<!--zuul 网关组件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>
<!--权限安全验证框架--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
<!--token生成工具-->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency>

以上是必须会用到的jar

项目结构:

代码(都是上面图片结构中的类的代码,直接复制,只要jar没错就不会出错):

package com.wdz.config;import com.wdz.filter.AuthenticationTokenFilter;
import com.wdz.util.exception.EntryPointUnauthorizedHandler;
import com.wdz.util.exception.MyAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration      // 声明为配置类
@EnableWebSecurity      // 启用 Spring Security web 安全的功能
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {/*** 注册 401 处理器*/@Autowiredprivate EntryPointUnauthorizedHandler unauthorizedHandler;/*** 注册 403 处理器*/@Autowiredprivate MyAccessDeniedHandler accessDeniedHandler;/*** 注册 token 转换拦截器为 bean* 如果客户端传来了 token ,那么通过拦截器解析 token 赋予用户权限** @return* @throws Exception*/@Beanpublic AuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {AuthenticationTokenFilter authenticationTokenFilter = new AuthenticationTokenFilter();authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());return authenticationTokenFilter;}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/getToken").permitAll()     // 所有人可以访问.anyRequest().authenticated()       // 必须携带token.and()// 配置被拦截时的处理.exceptionHandling().authenticationEntryPoint(this.unauthorizedHandler)   // 添加 token 无效或者没有携带 token 时的处理.accessDeniedHandler(this.accessDeniedHandler)      //添加无权限时的处理.and().csrf().disable()                      // 禁用 Spring Security 自带的跨域处理.sessionManagement()                        // 定制我们自己的 session 策略.sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 调整为让 Spring Security 不创建和使用 session/*** 本次 json web token 权限控制的核心配置部分* 在 Spring Security 开始判断本次会话是否有权限时的前一瞬间* 通过添加过滤器将 token 解析,将用户所有的权限写入本次会话*/http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);}
}

这个是controller类,用来获取token的

import com.wdz.entity.ApiUser;
import com.wdz.messgae.JsonResult;
import com.wdz.util.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;@RestController
public class TokenController {//@Autowired//private LoginService loginService;@Autowiredprivate TokenUtils tokenUtils;@PostMapping("/getToken")public JsonResult getToken(@RequestParam String username,@RequestParam String password){ApiUser apiUser=new ApiUser();apiUser.setUsername(username);apiUser.setPassword(password);apiUser.setEnable(1);JsonResult jsonResult=checkApiUser(apiUser,password);if (jsonResult!=null){return jsonResult;}String token=tokenUtils.generateToken(apiUser);return JsonResult.suc(token);}private JsonResult checkApiUser(ApiUser apiUser,String password){if (apiUser==null){return JsonResult.error(434,"账户不存在");}else {if (apiUser.getEnable()==0){return JsonResult.error(452,"账户在黑名单");}if (!apiUser.getPassword().equals(password)){//equals相等返回truereturn JsonResult.error(452,"账户密码错误");}}return null;}}
import com.wdz.util.TokenUtils;
import com.wdz.util.UserDetailImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;/*** @version V1.0.0* @Description 解析 token 的过滤器* 配置在 Spring Security 的配置类中* 用于解析 token ,将用户所有的权限写入本次 Spring Security 的会话中* @Author liuyuequn weanyq@gmail.com* @Date 2017年8月11日10:59:57*/
public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter {/*** json web token 在请求头的名字*/@Value("${token.header}")private String tokenHeader;/*** 辅助操作 token 的工具类*/@Autowiredprivate TokenUtils tokenUtils;/*** Spring Security 的核心操作服务类* 在当前类中将使用 UserDetailsService 来获取 userDetails 对象*///@Autowired//private UserDetailsServiceImpl userDetailsService;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 将 ServletRequest 转换为 HttpServletRequest 才能拿到请求头中的 tokenHttpServletRequest httpRequest = (HttpServletRequest) request;// 尝试获取请求头的 tokenString authToken =httpRequest.getHeader(this.tokenHeader);//获取token=xxx// 尝试拿 token 中的 username// 若是没有 token 或者拿 username 时出现异常,那么 username 为 nullString username = this.tokenUtils.getUsernameFromToken(authToken);// 如果上面解析 token 成功并且拿到了 username 并且本次会话的权限还未被写入if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {// 用 UserDetailsService 从数据库中拿到用户的 UserDetails 类// UserDetails 类是 Spring Security 用于保存用户权限的实体类UserDetails userDetails = new UserDetailImpl();// 检查用户带来的 token 是否有效// 包括 token 和 userDetails 中用户名是否一样, token 是否过期, token 生成时间是否在最后一次密码修改时间之前// 若是检查通过//if (this.tokenUtils.validateToken(authToken, userDetails)) {// 生成通过认证UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));// 将权限写入本次会话SecurityContextHolder.getContext().setAuthentication(authentication);// }//if (!userDetails.isEnabled()){// response.setCharacterEncoding("UTF-8");// response.setContentType("application/json;charset=UTF-8");//response.getWriter().print("{\"code\":\"452\",\"data\":\"\",\"message\":\"账号处于黑名单\"}");//return;// }}chain.doFilter(request, response);}}
public enum JsonCode {/* 成功状态码 */SUCCESS(0, "成功"),/* 失败状态码 */FAILED(9001,"失败"),/* 错误状态码 */ERROR(9002,"不存在该资源,请检查参数是否正确。");private Integer code;private String message;JsonCode(Integer code, String message) {this.code = code;this.message = message;}public Integer code() {return this.code;}public String message() {return this.message;}public static String getMessage(String name) {for (JsonCode item : JsonCode.values()) {if (item.name().equals(name)) {return item.message;}}return name;}public static Integer getCode(String name) {for (JsonCode item : JsonCode.values()) {if (item.name().equals(name)) {return item.code;}}return null;}@Overridepublic String toString() {return this.name();}}
public class JsonResult<T> {private Integer code;private String msg;private T data;//操作成功,有data数据public static JsonResult suc(Object data) {JsonResult result = new JsonResult();result.setResultCode(JsonCode.SUCCESS);result.setData(data);return result;}//运行错误,数据库连接错误public static JsonResult error() {JsonResult result = new JsonResult();result.setResultCode(JsonCode.ERROR);return result;}//运行错误,数据库连接错误public static JsonResult error(Integer code,String msg) {JsonResult result = new JsonResult();result.setCode(code);result.setMsg(msg);return result;}private void setResultCode(JsonCode code) {this.code = code.code();this.msg = code.message();}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint {/*** 未登录或无权限时触发的操作* 返回  {"code":401,"message":"没有携带 token 或者 token 无效!","data":""}* @param httpServletRequest* @param httpServletResponse* @param e* @throws IOException* @throws ServletException*/@Overridepublic void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {//返回json形式的错误信息httpServletResponse.setCharacterEncoding("UTF-8");httpServletResponse.setContentType("application/json");httpServletResponse.getWriter().println("{\"code\":401,\"message\":\"没有携带 token 或者 token 无效!\",\"data\":\"\"}");httpServletResponse.getWriter().flush();}}
public interface TokenDetail {// 这里封装了一层,不直接使用 username 做参数的原因是可以方便未来增加其他要封装到 token 中的信息String getUsername();
}
import com.wdz.entity.ApiUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;
import java.util.Date;public class SecurityModelFactory {public static UserDetailImpl create(ApiUser user) {Collection<? extends GrantedAuthority> authorities;try {authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(user.getAuthorities());} catch (Exception e) {authorities = null;}return new UserDetailImpl(user.getUsername(),user.getUsername(),user.getPassword(),authorities,user.enable());}}
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;
import java.util.Date;/*** @version V1.0.0* @Description 实现了 UserDetails 接口的模型类*              拓展了 UserDetails 的属性*              可以承载 创建 token 的日期,和 token 过期的日期*              用于判断用户传来的 token 是否可用* @Author liuyuequn weanyq@gmail.com* @Date 2017/8/2 19:03*/
public class UserDetailImpl implements UserDetails {// 开始定义必要的属性private String id;private String username;private String password;private Collection<? extends GrantedAuthority> authorities;private Boolean enabled;// 必要的属性定义完毕//开始定义 UserDetails 必要的属性,因为不打算启用这些限制条件,所以不对这些条件做限制,全部设置为 true (通过)private Boolean accountNonExpired = true;private Boolean accountNonLocked = true;private Boolean credentialsNonExpired = true;// 结束定义 UserDetails 必要的属性public UserDetailImpl() {super();}public UserDetailImpl(String id, String username, String password, Collection<? extends GrantedAuthority> authorities, Boolean enabled) {this.setId(id);this.setUsername(username);this.setPassword(password);this.setAuthorities(authorities);this.enabled = enabled;}public String getId() {return this.id;}public void setId(String id) {this.id = id;}public String getUsername() {return this.username;}public void setUsername(String username) {this.username = username;}@JsonIgnorepublic String getPassword() {return this.password;}public void setPassword(String password) {this.password = password;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return this.authorities;}public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {this.authorities = authorities;}@JsonIgnorepublic Boolean getAccountNonExpired() {return this.accountNonExpired;}public void setAccountNonExpired(Boolean accountNonExpired) {this.accountNonExpired = accountNonExpired;}@Overridepublic boolean isAccountNonExpired() {return this.getAccountNonExpired();}@JsonIgnorepublic Boolean getAccountNonLocked() {return this.accountNonLocked;}public void setAccountNonLocked(Boolean accountNonLocked) {this.accountNonLocked = accountNonLocked;}@Overridepublic boolean isAccountNonLocked() {return this.getAccountNonLocked();}@JsonIgnorepublic Boolean getCredentialsNonExpired() {return this.credentialsNonExpired;}public void setCredentialsNonExpired(Boolean credentialsNonExpired) {this.credentialsNonExpired = credentialsNonExpired;}@Overridepublic boolean isCredentialsNonExpired() {return this.getCredentialsNonExpired();}@JsonIgnorepublic Boolean getEnabled() {return this.enabled;}public void setEnabled(Boolean enabled) {this.enabled = enabled;}@Overridepublic boolean isEnabled() {return this.getEnabled();}}

application.yml:

# 构建路由地址
zuul:routes:# 这里可以自定义article:# 匹配的路由规则path: /**# 路由的目标服务名serviceId: article#访问本项目的接口需要这样写,getToken:path: /getToken/**url: forward:/getToken
token:secret: xsexpiration: 3600header: X_Auth_Token

Spring Zuul和Spring Security的整合相关推荐

  1. [摘]Spring 3之MVC Security简单整合开发

    为什么80%的码农都做不了架构师?>>>    参见: http://sarin.javaeye.com/blog/829738 转载于:https://my.oschina.net ...

  2. Spring Security OAuth2整合JWT

    文章目录 1. Spring Security 与 OAuth2 2. Spring Security OAuth2的配置和使用 ①:引入依赖 ②:配置 spring security ③:配置授权服 ...

  3. JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录

    文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...

  4. Spring Security(5) 整合OAuth2

    文章目录 一.前言 二.什么是OAuth2? 三.应用场景 四.三部分 五.四种授权模式 1. 授权码模式(authorization code) 2. 简化模式(implicit) 3. 密码模式( ...

  5. Spring Security 4 整合Hibernate 实现持久化登录验证(带源码)

    上一篇文章:Spring Security 4 整合Hibernate Bcrypt密码加密(带源码) 原文地址:http://websystique.com/spring-security/spri ...

  6. spring cloud alibaba 全家桶详细整合

    文章目录 本项目代码仓库地址 一.此次版本信息说明: 二.组件说明 三.新建聚合工程 3.1父工程pom文件 四.搭建整合nacos 五. 整合nacos 注册中心,新建cloud-system模块 ...

  7. JAVAspringboot微服务b2b Spring MVC+mybatis+spring cloud+spring boot+spring security

    鸿鹄云商大型企业分布式互联网电子商务平台,推出PC+微信+APP+云服务的云商平台系统,其中包括B2B.B2C.C2C.O2O.新零售.直播电商等子平台. 分布式.微服务.云架构电子商务平台 java ...

  8. java电子商务系统源码 Spring MVC+mybatis+spring cloud+spring boot+spring security

    鸿鹄云商大型企业分布式互联网电子商务平台,推出PC+微信+APP+云服务的云商平台系统,其中包括B2B.B2C.C2C.O2O.新零售.直播电商等子平台. 分布式.微服务.云架构电子商务平台 java ...

  9. 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...

最新文章

  1. python turtle库画图案-Python:turtle库的使用及图形绘制
  2. 三十三、深入Python中的itertools模块
  3. 安川机器人焊枪切换设定方法_安川机器人参数更改方法
  4. 批量删除指定user和transaction type对应order的report
  5. 深入Java核心:JVM中的栈和局部变量
  6. 关于近期对自己的总结
  7. Unity2020.2中支持的C#8有什么新特性?
  8. 开源视频平台:Kaltura
  9. oracle如何查找谁删除了数据_php如何删除session中数据
  10. C++11的std::declval与decltype
  11. 计算机界面没磁盘驱动器,驱动器中没有磁盘的原因和解决办法
  12. Java基础加强重温_06:可变参数、集合工具类Collections类、冒泡排序、Map集合、Map集合遍历、Map案例、LinkedHashMap集合、图书管理系统
  13. C++实现客户机(CLIENT)类
  14. 【OR】S Lemma
  15. 【bzoj1150】【CSTC2007】【数据备份】【贪心】
  16. 【Charles】charles unknown问题解决,及手机代理设置【iOS手机】
  17. 【NIPS 2017】PointNet++:度量空间中点集的深层次特征学习
  18. 金庸笔下用脚发暗器_移动的艺术:使用明暗器图创建动画材质
  19. 医疗行业大数据应用的三个案例
  20. Web安全之:WebShell的获取与查杀

热门文章

  1. 微信公众号h5支付完后无返回值,整个h5页面被关闭
  2. Apollo高精地图-1
  3. layui table获取分页当前页页码page
  4. mysql idata有什么用_IDataParameter有什么用,哪方面才用到
  5. Spring Boot+Mybatis:实现数据库登录注册与两种properties配置参数读取
  6. 男人吃3种籽能补肾生精
  7. Python—实操小实验之人机PK游戏(终极版本—应用类与对象的知识点应用)
  8. linux下 多python环境 修改默认python2为python3
  9. Android开发常见问题
  10. Tcl -- lappend