一 先理解以下架构图
二 程序的结构:
三 网关工程
- springsecurity配置
//网关的配置
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/doLogin")
.permitAll()
.anyRequest()
.authenticated()
.and()
// .addFilterBefore(new JwtAuthenticationFilter("/doLogin", authenticationManager()), UsernamePasswordAuthenticationFilter.class) //用户认证, 成功和失败的回调
.addFilterBefore(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); //资源的拦截的认证
http.csrf().disable();
http.headers().cacheControl();
//报错处理组件
http.exceptionHandling().accessDeniedHandler(new RestAuthorizationHandler())
.authenticationEntryPoint(new RestAuthenticationEntryPoint());
}
}
- 解决网关过滤敏感请求头的方法
- 在yml文件中配置,添加 sensitive-headers
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 9999
spring:
application:
name: jwt-gateway
zuul:
routes:
api-auth:
path: /doLogin
service-id: auth-center
api-microservice:
path: /microservice/**
service-id: jwt-microservice
sensitive-headers:
- 实现WebFilter,把敏感请求头加回来
@Component
public class WebFilter extends ZuulFilter {
/**
* true: 执行run()
* false: 不执行run()
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* Filter的主方法,具体的业务代码
* 要把敏感的请求头放加到请求中
*/
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
String token = request.getHeader("authorization");
System.out.println("zuul token:"+token);
if (token != null && !"".equals(token)) {
requestContext.addZuulRequestHeader("authorization", token);
}
return null;
}
@Override
public String filterType() {
return FilterConstants.PRE_TYPE; //路由之前过滤
}
@Override
public int filterOrder() {
return 0;
}
}
四 验证中心
配置类
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SysUserService sysUserService;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("帐号:" + username);
SysUser user = sysUserService.findUserByUsercode(username);
if (user != null) {
Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
return new UserDetailImpl(user, authorities );
}
throw new UsernameNotFoundException("帐号或密码错误");
}
};
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/doLogin")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(new JwtAuthencationFilter("/doLogin", authenticationManager()), UsernamePasswordAuthenticationFilter.class); //用户认证, 成功和失败的回调
//.addFilterBefore(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); //资源的拦截的认证
http.csrf().disable();
http.headers().cacheControl();
//报错处理组件
http.exceptionHandling().accessDeniedHandler(new RestAuthorizationHandler())
.authenticationEntryPoint(new RestAuthenticationEntryPoint());
}
}
五 前端angular访问jwt
- 用户认证前端实现
- 前端拦截器实现
- 后台服务访问