微服务项目构建认证中心(SpringSecurity+JWT)

网友投稿 446 2022-09-28

微服务项目构建认证中心(SpringSecurity+JWT)

前言,毕设项目中,由于只考虑web端的,没考虑客户端,所以没有用oauth2(其实也是因为没掌握,尴尬)

一、项目准备

父项目,建立统一管理,pom.xml

String createToken(T userInfo, PrivateKey privateKey,int expire) throws JsonProcessingException{ //设置过期时间 //获取当前时间 Calendar calendar = Calendar.getInstance(); //在当前时间加上过期时间 calendar.add(Calendar.SECOND,expire); //将userInfo对象转为Json String userInfoJson = new ObjectMapper().writeValueAsString(userInfo); //生成token return Jwts.builder()//获得Jwt的编译对象 .claim(JWT_PAYLOAD_USER_KEY,userInfoJson)//设置负载,负载内容为JSON字符串 .setExpiration(calendar.getTime())//设置过期时间 .signWith(SignatureAlgorithm.RS256, privateKey)//设置签名,使用私钥做为签名 .compact();//生成token }}

SysUserDetails扩展类

package com.jc.springcloud.common;/** * @program: hg_blog * @description: * @author: hjc * @create: 2022-01-03 14:40 **/@Data@AllArgsConstructor@NoArgsConstructorpublic class SysUserDetails implements UserDetails { //扩展字段 private Integer user_id; //默认字段 private String username; private String password; private boolean isAccountNonLocked; private Collection authorities; @Override public Collection getAuthorities() { return this.authorities; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; }}

SecurityConfig类

package com.jc.springcloud.config;/** * @program: hg_blog * @description: Security配置 * @author: hjc * @create: 2022-01-02 19:50 **/@Configuration@EnableWebSecurity@Slf4jpublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity throws Exception { .cors()//开启security对跨域的支持 .and() .formLogin()//登录设置 .loginPage("/login")//登录处理器 .and() .csrf() .disable();//禁用跨域伪造检测 BlogUsernamePasswordAuthenticationFilter(authenticationManager())); }}

BlogUsernamePasswordAuthenticationFilter

package com.jc.springcloud.filter;/** * @program: hg_blog * @description: 当用户登录时会自动执行该过滤器 * @author: hjc * @create: 2022-01-04 14:26 **/@Slf4jpublic class BlogUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { //过期时间一天 private final int ACTIVE_TIME = 60 * 60 * 24;// private final int ACTIVE_TIME = 60 * 2; //设置认证管理器属性 private AuthenticationManager authenticationManager; public BlogUsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager){ this.authenticationManager = authenticationManager; } /*** * @description 用于获取客户端提交的数据,提交的数据处理后会交给UserDetailsService继续执行 * @param request * @param response * @return org.springframework.security.core.Authentication * @author hjc * CreateDate 2022/1/4 14:45 */ @SneakyThrows @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { log.info("attemptAuthentication被执行"); //获取客户端传入的payload参数 LoginInfo loginInfo = new ObjectMapper().readValue(request.getInputStream(), LoginInfo.class); log.info(String.valueOf(loginInfo)); //创建认证令牌并将认证信息传入 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginInfo.getUsername(), loginInfo.getPassword()); //将认证令牌提交给认证管理器,认证管理器会将authRequest交给UserDetailsService处理 return authenticationManager.authenticate(authenticationToken); } /*** * @description 当用户登录成功后执行该方法,它在UserDetailsService认证成功后执行 * 在该方法中使用私钥生成token,并将token发送到客户端 * @param request * @param response * @param chain * @param authResult * @return void * @author hjc * CreateDate 2022/1/4 14:48 */ @SneakyThrows @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { log.info("登录成功!"); response.setContentType("application/json;charset=utf-8"); //从认证信息中获取用户数据,并设置在payload集合中 SysUserDetails sysUserDetails = (SysUserDetails) authResult.getPrincipal(); log.info(String.valueOf(sysUserDetails)); //创建jwt负载的map集合并设置相关数据 Map payloadMap = new HashMap(){{ put("user_id",sysUserDetails.getUser_id());//当前登录者的id put("auth",sysUserDetails.getAuthorities());//当前账户的权限集合 }}; //获取私钥 PrivateKey privateKey = JwtUtil.getPrivateKey(); //使用私钥和过期时间生成token String token = JwtUtil.createToken(payloadMap,privateKey,ACTIVE_TIME); PrintWriter writer = response.getWriter(); writer.print(JSON.toJSONString(CommonResult.success("登录成功!",token))); writer.flush(); writer.close(); } /*** * @description 用户登录失败后执行该方法,它在UserDetailsService认证失败后执行 * @param request * @param response * @param failed * @return void * @author hjc * CreateDate 2022/1/4 15:55 */ @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { log.info("登录失败,unsuccessfulAuthentication"); response.setContentType("application/json;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.print(JSON.toJSONString(CommonResult.fail(HttpServletResponse.SC_UNAUTHORIZED,failed.getMessage()))); writer.flush(); writer.close(); }}

AuthMapper

package com.jc.springcloud.mapper;/** * @program: hg_blog * @description: * @author: hjc * @create: 2022-01-03 12:35 **/@Mapperpublic interface AuthMapper { //登录 @Select("select user_id,user_phone,user_password,is_superuser,is_lock from hb_user where user_phone = #{user_phone}") public HbUserInfo queryLoginByPhone(String user_phone);}

SysUserDetailsServiceImpl

package com.jc.springcloud.service.impl;/** * @program: hg_blog * @description: UserDetailsService实现类,该类交给Spring管理后,Security会在登录时自动查找UserDetailsService的实现类 * @author: hjc * @create: 2022-01-03 14:47 **/@Slf4j@Servicepublic class SysUserDetailsServiceImpl implements UserDetailsService { @Resource private AuthMapper authMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { log.info("执行UserDetailsServiceImpl"); //根据用户名及手机号查询用户信息 HbUserInfo hbUserInfo = authMapper.queryLoginByPhone(username); if (hbUserInfo == null){ throw new UsernameNotFoundException("用户不存在!"); } Collection authorities = new ArrayList<>(); if (hbUserInfo.getIs_superuser() == 0){ authorities.add(new SimpleGrantedAuthority("ROLE_USER")); }else { authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); } return new SysUserDetails( hbUserInfo.getUser_id(), hbUserInfo.getUser_phone(), hbUserInfo.getUser_password(), hbUserInfo.getIs_lock() == 0 ? true : false, authorities); }}

三、测试

​​网关统一鉴权中心​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SAP BTP MTA 应用解决的架构痛点
下一篇:Java两整数相除向上取整的方式详解(Math.ceil())
相关文章

 发表评论

暂时没有评论,来抢沙发吧~